@Override @SuppressWarnings("unchecked") public BitSet<T> addAll(Iterable<? extends T> elements) { final Stream<Integer> source = Stream.ofAll(elements).map(toInt); if (source.isEmpty()) { return this; } else { final long[] copy = copyExpand(1 + (source.max().getOrElse(0) >> ADDRESS_BITS_PER_WORD)); source.forEach(element -> { if (element < 0) { throw new IllegalArgumentException("bitset element must be >= 0"); } setElement(copy, element); }); final BitSet<T> bitSet = fromBitMaskNoCopy(copy); return (bitSet.length() == length()) ? this : bitSet; } }
@Override public BitSet<T> intersect(Set<? extends T> elements) { Objects.requireNonNull(elements, "elements is null"); if (isEmpty()) { return this; } else if (elements.isEmpty()) { return createEmpty(); } else { final int size = size(); if (size <= elements.size()) { return retainAll(elements); } else { final BitSet<T> results = createFromAll(elements).retainAll(this); return (size == results.size()) ? this : results; } } }
@Override public BitSet<T> init() { if (isEmpty()) { throw new UnsupportedOperationException("init of empty TreeSet"); } else { final long last = getWord(getWordsNum() - 1); final int element = BITS_PER_WORD * (getWordsNum() - 1) + BITS_PER_WORD - Long.numberOfLeadingZeros(last) - 1; return remove(fromInt.apply(element)); } }
@Override @SuppressWarnings("unchecked") public BitSet<T> addAll(Iterable<? extends T> elements) { final Stream<Integer> source = Stream.ofAll(elements).map(toInt); if (source.isEmpty()) { return this; } else { final long[] copy = copyExpand(1 + (source.max().getOrElse(0) >> ADDRESS_BITS_PER_WORD)); source.forEach(element -> { if (element < 0) { throw new IllegalArgumentException("bitset element must be >= 0"); } setElement(copy, element); }); final BitSet<T> bitSet = fromBitMaskNoCopy(copy); return (bitSet.length() == length()) ? this : bitSet; } }
@Override public BitSet<T> intersect(Set<? extends T> elements) { Objects.requireNonNull(elements, "elements is null"); if (isEmpty()) { return this; } else if (elements.isEmpty()) { return createEmpty(); } else { final int size = size(); if (size <= elements.size()) { return retainAll(elements); } else { final BitSet<T> results = createFromAll(elements).retainAll(this); return (size == results.size()) ? this : results; } } }
@SuppressWarnings("unchecked") BitSet<T> createFromAll(Iterable<? extends T> values) { return values instanceof BitSet ? (BitSet<T>) values : createEmpty().addAll(values); }
@Override public BitSet<T> removeAll(Iterable<? extends T> elements) { if (isEmpty()) { return this; } else { final Stream<Integer> source = Stream.ofAll(elements).map(toInt); if (source.isEmpty()) { return this; } else { final long[] copy = copyExpand(getWordsNum()); source.forEach(element -> unsetElement(copy, element)); return fromBitMaskNoCopy(shrink(copy)); } } }
@Override public Iterator<BitSet<T>> sliding(int size, int step) { return iterator().sliding(size, step).map(this::createFromAll); }
@Override public Iterator<BitSet<T>> slideBy(Function<? super T, ?> classifier) { return iterator().slideBy(classifier).map(this::createFromAll); }
@Override public Tuple2<BitSet<T>, BitSet<T>> partition(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); return iterator().partition(predicate).map(this::createFromAll, this::createFromAll); }
BitSet<T> fromBitMaskNoCopy(long[] elements) { switch (elements.length) { case 0: return createEmpty(); case 1: return new BitSet1<>(fromInt, toInt, elements[0]); case 2: return new BitSet2<>(fromInt, toInt, elements[0], elements[1]); default: return new BitSetN<>(fromInt, toInt, elements); } }
/** * Returns this {@code BitSet} if it is nonempty, * otherwise {@code BitSet} created from result of evaluating supplier, using existing bitset properties. * * @param supplier An alternative {@code Traversable} * @return this {@code BitSet} if it is nonempty, * otherwise {@code BitSet} created from result of evaluating supplier, using existing bitset properties. */ @Override public BitSet<T> orElse(Supplier<? extends Iterable<? extends T>> supplier) { return isEmpty() ? createFromAll(supplier.get()) : this; }
/** * Returns this {@code BitSet} if it is nonempty, * otherwise {@code BitSet} created from iterable, using existing bitset properties. * * @param other An alternative {@code Traversable} * @return this {@code BitSet} if it is nonempty, * otherwise {@code BitSet} created from iterable, using existing bitset properties. */ @Override public BitSet<T> orElse(Iterable<? extends T> other) { return isEmpty() ? createFromAll(other) : this; }
@Override public boolean contains(T t) { final int element = toInt.apply(t); if (element < 0) { throw new IllegalArgumentException("bitset element must be >= 0"); } final int index = element >> ADDRESS_BITS_PER_WORD; return index < getWordsNum() && (getWord(index) & (1L << element)) != 0; }
@Override public BitSet<T> distinctBy(Comparator<? super T> comparator) { Objects.requireNonNull(comparator, "comparator is null"); return isEmpty() ? this : createFromAll(iterator().distinctBy(comparator)); }
@Override public BitSet<T> takeWhile(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); final BitSet<T> result = createFromAll(iterator().takeWhile(predicate)); return (result.length() == length()) ? this : result; }
@Override public BitSet<T> reject(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); final BitSet<T> bitSet = createFromAll(iterator().reject(predicate)); return (bitSet.length() == length()) ? this : bitSet; }
@Override public boolean hasNext() { if (element == 0) { while (element == 0 && index < bitSet.getWordsNum() - 1) { element = bitSet.getWord(++index); } return element != 0; } else { return true; } } }
BitSet<T> addElement(int element) { final long[] copy = copyExpand(1 + (element >> ADDRESS_BITS_PER_WORD)); setElement(copy, element); return fromBitMaskNoCopy(copy); }
@Override public BitSet<T> filter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate, "predicate is null"); final BitSet<T> bitSet = createFromAll(iterator().filter(predicate)); return (bitSet.length() == length()) ? this : bitSet; }