/*
 * Copyright (c) 2018 Goldman Sachs and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v. 1.0 which accompany this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 */

package org.eclipse.collections.impl.set.mutable.primitive;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
import java.util.Arrays;
import java.util.NoSuchElementException;

import org.eclipse.collections.api.ByteIterable;
import org.eclipse.collections.api.LazyByteIterable;
import org.eclipse.collections.api.RichIterable;
import org.eclipse.collections.api.bag.primitive.MutableByteBag;
import org.eclipse.collections.api.block.function.primitive.ByteToObjectFunction;
import org.eclipse.collections.api.block.function.primitive.ObjectByteToObjectFunction;
import org.eclipse.collections.api.block.predicate.primitive.BytePredicate;
import org.eclipse.collections.api.block.procedure.primitive.ByteProcedure;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.iterator.ByteIterator;
import org.eclipse.collections.api.iterator.MutableByteIterator;
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.api.list.primitive.MutableByteList;
import org.eclipse.collections.api.set.ImmutableSet;
import org.eclipse.collections.api.set.MutableSet;
import org.eclipse.collections.api.set.primitive.ByteSet;
import org.eclipse.collections.api.set.primitive.ImmutableByteSet;
import org.eclipse.collections.api.set.primitive.MutableByteSet;
import org.eclipse.collections.impl.bag.mutable.primitive.ByteHashBag;
import org.eclipse.collections.impl.block.procedure.checked.primitive.CheckedByteProcedure;
import org.eclipse.collections.impl.factory.primitive.ByteSets;
import org.eclipse.collections.impl.lazy.primitive.LazyByteIterableAdapter;
import org.eclipse.collections.impl.list.mutable.primitive.ByteArrayList;
import org.eclipse.collections.impl.set.immutable.primitive.ImmutableByteSetSerializationProxy;
import org.eclipse.collections.impl.set.mutable.UnifiedSet;

public final class ByteHashSet implements MutableByteSet, Externalizable
{
    private static final long serialVersionUID = 1L;
    private static final byte MAX_BYTE_GROUP_1 = -65;
    private static final byte MAX_BYTE_GROUP_2 = -1;
    private static final byte MAX_BYTE_GROUP_3 = 63;
    private long bitGroup1; // -128 to -65
    private long bitGroup2; //-64 to -1
    private long bitGroup3; //0 to 63
    private long bitGroup4; // 64 to 127
    private short size;

    public ByteHashSet()
    {
    }

    
Use ByteHashSet() instead.
Deprecated:since 5.0.
/** * Use {@link ByteHashSet#ByteHashSet()} instead. * * @deprecated since 5.0. */
@Deprecated public ByteHashSet(int initialCapacity) { if (initialCapacity < 0) { throw new IllegalArgumentException("initial capacity cannot be less than 0"); } } public ByteHashSet(ByteHashSet set) { this.size = set.size; this.bitGroup3 = set.bitGroup3; this.bitGroup4 = set.bitGroup4; this.bitGroup1 = set.bitGroup1; this.bitGroup2 = set.bitGroup2; } public ByteHashSet(byte... elements) { this(); this.addAll(elements); } public static ByteHashSet newSet(ByteIterable source) { if (source instanceof ByteHashSet) { return new ByteHashSet((ByteHashSet) source); } return ByteHashSet.newSetWith(source.toArray()); } public static ByteHashSet newSetWith(byte... source) { return new ByteHashSet(source); } @Override public boolean add(byte element) { if (element <= MAX_BYTE_GROUP_1) { long initial = this.bitGroup1; this.bitGroup1 |= 1L << (byte) ((element + 1) * -1); if (this.bitGroup1 != initial) { this.size++; return true; } } else if (element <= MAX_BYTE_GROUP_2) { long initial = this.bitGroup2; this.bitGroup2 |= 1L << (byte) ((element + 1) * -1); if (this.bitGroup2 != initial) { this.size++; return true; } } else if (element <= MAX_BYTE_GROUP_3) { long initial = this.bitGroup3; this.bitGroup3 |= 1L << element; if (this.bitGroup3 != initial) { this.size++; return true; } } else { long initial = this.bitGroup4; this.bitGroup4 |= 1L << element; if (this.bitGroup4 != initial) { this.size++; return true; } } return false; } @Override public boolean remove(byte value) { if (value <= MAX_BYTE_GROUP_1) { long initial = this.bitGroup1; this.bitGroup1 &= ~(1L << (byte) ((value + 1) * -1)); if (this.bitGroup1 == initial) { return false; } this.size--; return true; } if (value <= MAX_BYTE_GROUP_2) { long initial = this.bitGroup2; this.bitGroup2 &= ~(1L << (byte) ((value + 1) * -1)); if (this.bitGroup2 == initial) { return false; } this.size--; return true; } if (value <= MAX_BYTE_GROUP_3) { long initial = this.bitGroup3; this.bitGroup3 &= ~(1L << value); if (this.bitGroup3 == initial) { return false; } this.size--; return true; } long initial = this.bitGroup4; this.bitGroup4 &= ~(1L << value); if (this.bitGroup4 == initial) { return false; } this.size--; return true; } @Override public boolean contains(byte value) { if (value <= MAX_BYTE_GROUP_1) { return ((this.bitGroup1 >>> (byte) ((value + 1) * -1)) & 1L) != 0; } if (value <= MAX_BYTE_GROUP_2) { return ((this.bitGroup2 >>> (byte) ((value + 1) * -1)) & 1L) != 0; } if (value <= MAX_BYTE_GROUP_3) { return ((this.bitGroup3 >>> value) & 1L) != 0; } return ((this.bitGroup4 >>> value) & 1L) != 0; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof ByteSet)) { return false; } ByteSet other = (ByteSet) obj; return this.size() == other.size() && this.containsAll(other.toArray()); } @Override public int hashCode() { return (int) this.sum(); } @Override public String toString() { return this.makeString("[", ", ", "]"); } @Override public int size() { return this.size; } @Override public boolean isEmpty() { return this.size() == 0; } @Override public boolean notEmpty() { return this.size() != 0; } @Override public String makeString() { return this.makeString(", "); } @Override public String makeString(String separator) { return this.makeString("", separator, ""); } @Override public String makeString(String start, String separator, String end) { Appendable stringBuilder = new StringBuilder(); this.appendString(stringBuilder, start, separator, end); return stringBuilder.toString(); } @Override public void appendString(Appendable appendable) { this.appendString(appendable, ", "); } @Override public void appendString(Appendable appendable, String separator) { this.appendString(appendable, "", separator, ""); } @Override public void appendString(Appendable appendable, String start, String separator, String end) { try { appendable.append(start); int count = 0; ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { if (count > 0) { appendable.append(separator); } count++; appendable.append(String.valueOf(iterator.next())); } appendable.append(end); } catch (IOException e) { throw new RuntimeException(e); } } @Override public boolean addAll(byte... source) { int oldSize = this.size(); for (byte item : source) { this.add(item); } return this.size() != oldSize; } @Override public boolean addAll(ByteIterable source) { if (source.isEmpty()) { return false; } int oldSize = this.size(); if (source instanceof ByteHashSet) { ByteHashSet hashSet = (ByteHashSet) source; this.size = 0; this.bitGroup3 |= hashSet.bitGroup3; this.size += Long.bitCount(this.bitGroup3); this.bitGroup4 |= hashSet.bitGroup4; this.size += Long.bitCount(this.bitGroup4); this.bitGroup2 |= hashSet.bitGroup2; this.size += Long.bitCount(this.bitGroup2); this.bitGroup1 |= hashSet.bitGroup1; this.size += Long.bitCount(this.bitGroup1); } else { ByteIterator iterator = source.byteIterator(); while (iterator.hasNext()) { byte item = iterator.next(); this.add(item); } } return this.size() != oldSize; } @Override public boolean removeAll(ByteIterable source) { if (source.isEmpty()) { return false; } int oldSize = this.size(); if (source instanceof ByteHashSet) { this.size = 0; ByteHashSet hashSet = (ByteHashSet) source; this.bitGroup3 &= ~hashSet.bitGroup3; this.size += Long.bitCount(this.bitGroup3); this.bitGroup4 &= ~hashSet.bitGroup4; this.size += Long.bitCount(this.bitGroup4); this.bitGroup2 &= ~hashSet.bitGroup2; this.size += Long.bitCount(this.bitGroup2); this.bitGroup1 &= ~hashSet.bitGroup1; this.size += Long.bitCount(this.bitGroup1); } else { ByteIterator iterator = source.byteIterator(); while (iterator.hasNext()) { byte item = iterator.next(); this.remove(item); } } return this.size() != oldSize; } @Override public boolean removeAll(byte... source) { if (source.length == 0) { return false; } int oldSize = this.size(); for (byte item : source) { this.remove(item); } return this.size() != oldSize; } @Override public boolean retainAll(ByteIterable source) { int oldSize = this.size(); ByteSet sourceSet = source instanceof ByteSet ? (ByteSet) source : source.toSet(); ByteHashSet retained = this.select(sourceSet::contains); if (retained.size() != oldSize) { this.bitGroup3 = retained.bitGroup3; this.bitGroup4 = retained.bitGroup4; this.bitGroup1 = retained.bitGroup1; this.bitGroup2 = retained.bitGroup2; this.size = retained.size; return true; } return false; } @Override public boolean retainAll(byte... source) { return this.retainAll(ByteHashSet.newSetWith(source)); } @Override public void clear() { this.size = 0; this.bitGroup3 = 0L; this.bitGroup4 = 0L; this.bitGroup1 = 0L; this.bitGroup2 = 0L; } @Override public ByteHashSet with(byte element) { this.add(element); return this; } @Override public ByteHashSet without(byte element) { this.remove(element); return this; } @Override public ByteHashSet withAll(ByteIterable elements) { this.addAll(elements.toArray()); return this; } @Override public ByteHashSet withoutAll(ByteIterable elements) { this.removeAll(elements); return this; } @Override public MutableByteSet asUnmodifiable() { return new UnmodifiableByteSet(this); } @Override public MutableByteSet asSynchronized() { return new SynchronizedByteSet(this); } @Override public ImmutableByteSet toImmutable() { if (this.size() == 0) { return ByteSets.immutable.with(); } if (this.size() == 1) { return ByteSets.immutable.with(this.byteIterator().next()); } ByteHashSet mutableSet = ByteHashSet.newSetWith(this.toArray()); return new ImmutableByteHashSet(mutableSet.bitGroup3, mutableSet.bitGroup4, mutableSet.bitGroup1, mutableSet.bitGroup2, mutableSet.size); }
Since:9.2.
/** * @since 9.2. */
@Override public ByteHashSet newEmpty() { return new ByteHashSet(); } @Override public MutableByteIterator byteIterator() { return new MutableInternalByteIterator(); } @Override public byte[] toArray() { byte[] array = new byte[this.size()]; int index = 0; ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { byte nextByte = iterator.next(); array[index] = nextByte; index++; } return array; } @Override public byte[] toArray(byte[] array) { if (array.length < this.size()) { array = new byte[this.size()]; } int index = 0; ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { byte nextByte = iterator.next(); array[index] = nextByte; index++; } return array; } @Override public boolean containsAll(byte... source) { for (byte item : source) { if (!this.contains(item)) { return false; } } return true; } @Override public boolean containsAll(ByteIterable source) { for (ByteIterator iterator = source.byteIterator(); iterator.hasNext(); ) { if (!this.contains(iterator.next())) { return false; } } return true; } @Override public void forEach(ByteProcedure procedure) { this.each(procedure); }
Since:7.0.
/** * @since 7.0. */
@Override public void each(ByteProcedure procedure) { long bitGroup1 = this.bitGroup1; while (bitGroup1 != 0L) { byte value = (byte) Long.numberOfTrailingZeros(bitGroup1); procedure.value((byte) ((value + 65) * -1)); bitGroup1 &= ~(1L << (byte) (value + 64)); } long bitGroup2 = this.bitGroup2; while (bitGroup2 != 0L) { byte value = (byte) Long.numberOfTrailingZeros(bitGroup2); procedure.value((byte) ((value + 1) * -1)); bitGroup2 &= ~(1L << value); } long bitGroup3 = this.bitGroup3; while (bitGroup3 != 0L) { byte value = (byte) Long.numberOfTrailingZeros(bitGroup3); procedure.value(value); bitGroup3 &= ~(1L << value); } long bitGroup4 = this.bitGroup4; while (bitGroup4 != 0L) { byte value = (byte) Long.numberOfTrailingZeros(bitGroup4); procedure.value((byte) (value + 64)); bitGroup4 &= ~(1L << (byte) (value + 64)); } } @Override public ByteHashSet select(BytePredicate predicate) { ByteHashSet result = new ByteHashSet(); this.forEach(value -> { if (predicate.accept(value)) { result.add(value); } }); return result; } @Override public MutableByteSet reject(BytePredicate predicate) { MutableByteSet result = new ByteHashSet(); this.forEach(value -> { if (!predicate.accept(value)) { result.add(value); } }); return result; } @Override public <V> MutableSet<V> collect(ByteToObjectFunction<? extends V> function) { MutableSet<V> target = UnifiedSet.newSet(this.size()); this.forEach(each -> target.add(function.valueOf(each))); return target; } @Override public byte detectIfNone(BytePredicate predicate, byte ifNone) { ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { byte nextByte = iterator.next(); if (predicate.accept(nextByte)) { return nextByte; } } return ifNone; } @Override public int count(BytePredicate predicate) { int count = 0; ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { if (predicate.accept(iterator.next())) { count++; } } return count; } @Override public boolean anySatisfy(BytePredicate predicate) { ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { if (predicate.accept(iterator.next())) { return true; } } return false; } @Override public boolean allSatisfy(BytePredicate predicate) { ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { if (!predicate.accept(iterator.next())) { return false; } } return true; } @Override public boolean noneSatisfy(BytePredicate predicate) { ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { if (predicate.accept(iterator.next())) { return false; } } return true; } @Override public MutableByteList toList() { return ByteArrayList.newList(this); } @Override public MutableByteSet toSet() { return ByteHashSet.newSet(this); } @Override public MutableByteBag toBag() { return ByteHashBag.newBag(this); } @Override public LazyByteIterable asLazy() { return new LazyByteIterableAdapter(this); } @Override public long sum() { long result = 0L; ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { result += iterator.next(); } return result; } @Override public byte max() { if (this.isEmpty()) { throw new NoSuchElementException(); } byte max = 0; if (this.bitGroup4 != 0L) { //the highest has to be from this max = (byte) (127 - Long.numberOfLeadingZeros(this.bitGroup4)); } else if (this.bitGroup3 != 0L) { max = (byte) (63 - Long.numberOfLeadingZeros(this.bitGroup3)); } else if (this.bitGroup2 != 0L) { max = (byte) ((Long.numberOfTrailingZeros(this.bitGroup2) + 1) * -1); } else if (this.bitGroup1 != 0L) { max = (byte) ((Long.numberOfTrailingZeros(this.bitGroup1) + 65) * -1); } return max; } @Override public byte maxIfEmpty(byte defaultValue) { if (this.isEmpty()) { return defaultValue; } return this.max(); } @Override public byte min() { if (this.isEmpty()) { throw new NoSuchElementException(); } byte min = 0; if (this.bitGroup1 != 0L) { //the minimum has to be from this min = (byte) (128 - Long.numberOfLeadingZeros(this.bitGroup1)); min *= -1; } else if (this.bitGroup2 != 0L) { min = (byte) ((64 - Long.numberOfLeadingZeros(this.bitGroup2)) * -1); } else if (this.bitGroup3 != 0L) { min = (byte) Long.numberOfTrailingZeros(this.bitGroup3); } else if (this.bitGroup4 != 0L) { min = (byte) (Long.numberOfTrailingZeros(this.bitGroup4) + 64); } return min; } @Override public byte minIfEmpty(byte defaultValue) { if (this.isEmpty()) { return defaultValue; } return this.min(); } @Override public double average() { if (this.isEmpty()) { throw new ArithmeticException(); } return (double) this.sum() / (double) this.size(); } @Override public double median() { if (this.isEmpty()) { throw new ArithmeticException(); } byte[] sortedArray = this.toSortedArray(); int middleIndex = sortedArray.length >> 1; if (sortedArray.length > 1 && (sortedArray.length & 1) == 0) { byte first = sortedArray[middleIndex]; byte second = sortedArray[middleIndex - 1]; return ((double) first + (double) second) / 2.0; } return (double) sortedArray[middleIndex]; } @Override public byte[] toSortedArray() { byte[] array = this.toArray(); Arrays.sort(array); return array; } @Override public MutableByteList toSortedList() { return ByteArrayList.newList(this).sortThis(); } @Override public ByteSet freeze() { if (this.size() == 0) { return ByteSets.immutable.with(); } if (this.size() == 1) { return ByteSets.immutable.with(this.byteIterator().next()); } return new ImmutableByteHashSet(this.bitGroup3, this.bitGroup4, this.bitGroup1, this.bitGroup2, this.size); } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeInt(this.size()); this.forEach(new CheckedByteProcedure() { public void safeValue(byte each) throws IOException { out.writeByte(each); } }); } @Override public void readExternal(ObjectInput in) throws IOException { int size = in.readInt(); for (int i = 0; i < size; i++) { this.add(in.readByte()); } } @Override public <T> T injectInto(T injectedValue, ObjectByteToObjectFunction<? super T, ? extends T> function) { T result = injectedValue; ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { result = function.valueOf(result, iterator.next()); } return result; } @Override public RichIterable<ByteIterable> chunk(int size) { if (size <= 0) { throw new IllegalArgumentException("Size for groups must be positive but was: " + size); } MutableList<ByteIterable> result = Lists.mutable.empty(); if (this.notEmpty()) { if (this.size() <= size) { result.add(ByteSets.mutable.withAll(this)); } else { ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { MutableByteSet batch = ByteSets.mutable.empty(); for (int i = 0; i < size && iterator.hasNext(); i++) { batch.add(iterator.next()); } result.add(batch); } } } return result; } private static final class ImmutableByteHashSet implements ImmutableByteSet, Serializable { private static final long serialVersionUID = 1L; private final long bitGroup1; // -128 to -65 private final long bitGroup2; //-64 to -1 private final long bitGroup3; //0 to 63 private final long bitGroup4; // 64 to 127 private final short size; private ImmutableByteHashSet( long bitGroup3, long bitGroup4, long bitGroup1, long bitGroup2, short size) { this.bitGroup3 = bitGroup3; this.bitGroup4 = bitGroup4; this.bitGroup1 = bitGroup1; this.bitGroup2 = bitGroup2; this.size = size; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof ByteSet)) { return false; } ByteSet other = (ByteSet) obj; return this.size() == other.size() && this.containsAll(other.toArray()); } @Override public int hashCode() { return (int) this.sum(); } @Override public String toString() { return this.makeString("[", ", ", "]"); } @Override public ImmutableByteSet newWith(byte element) { return ByteHashSet.newSet(this).with(element).toImmutable(); } @Override public ImmutableByteSet newWithout(byte element) { return ByteHashSet.newSet(this).without(element).toImmutable(); } @Override public ImmutableByteSet newWithAll(ByteIterable elements) { return ByteHashSet.newSet(this).withAll(elements).toImmutable(); } @Override public ImmutableByteSet newWithoutAll(ByteIterable elements) { return ByteHashSet.newSet(this).withoutAll(elements).toImmutable(); } @Override public int size() { return this.size; } @Override public boolean isEmpty() { return this.size() == 0; } @Override public boolean notEmpty() { return this.size() != 0; } @Override public String makeString() { return this.makeString(", "); } @Override public String makeString(String separator) { return this.makeString("", separator, ""); } @Override public String makeString(String start, String separator, String end) { Appendable stringBuilder = new StringBuilder(); this.appendString(stringBuilder, start, separator, end); return stringBuilder.toString(); } @Override public void appendString(Appendable appendable) { this.appendString(appendable, ", "); } @Override public void appendString(Appendable appendable, String separator) { this.appendString(appendable, "", separator, ""); } @Override public void appendString(Appendable appendable, String start, String separator, String end) { try { appendable.append(start); int count = 0; ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { byte nextByte = iterator.next(); if (count > 0) { appendable.append(separator); } count++; appendable.append(String.valueOf(nextByte)); } appendable.append(end); } catch (IOException e) { throw new RuntimeException(e); } } @Override public ByteIterator byteIterator() { return new InternalByteIterator(); } @Override public byte[] toArray() { byte[] array = new byte[this.size()]; int index = 0; ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { byte nextByte = iterator.next(); array[index] = nextByte; index++; } return array; } @Override public byte[] toArray(byte[] array) { if (array.length < this.size()) { array = new byte[this.size()]; } int index = 0; ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { byte nextByte = iterator.next(); array[index] = nextByte; index++; } return array; } @Override public boolean contains(byte value) { if (value <= MAX_BYTE_GROUP_1) { return ((this.bitGroup1 >>> (byte) ((value + 1) * -1)) & 1L) != 0; } if (value <= MAX_BYTE_GROUP_2) { return ((this.bitGroup2 >>> (byte) ((value + 1) * -1)) & 1L) != 0; } if (value <= MAX_BYTE_GROUP_3) { return ((this.bitGroup3 >>> value) & 1L) != 0; } return ((this.bitGroup4 >>> value) & 1L) != 0; } @Override public boolean containsAll(byte... source) { for (byte item : source) { if (!this.contains(item)) { return false; } } return true; } @Override public boolean containsAll(ByteIterable source) { for (ByteIterator iterator = source.byteIterator(); iterator.hasNext(); ) { if (!this.contains(iterator.next())) { return false; } } return true; } @Override public void forEach(ByteProcedure procedure) { this.each(procedure); } @Override public void each(ByteProcedure procedure) { long bitGroup1 = this.bitGroup1; while (bitGroup1 != 0L) { byte value = (byte) Long.numberOfTrailingZeros(bitGroup1); procedure.value((byte) ((value + 65) * -1)); bitGroup1 &= ~(1L << (byte) (value + 64)); } long bitGroup2 = this.bitGroup2; while (bitGroup2 != 0L) { byte value = (byte) Long.numberOfTrailingZeros(bitGroup2); procedure.value((byte) ((value + 1) * -1)); bitGroup2 &= ~(1L << value); } long bitGroup3 = this.bitGroup3; while (bitGroup3 != 0L) { byte value = (byte) Long.numberOfTrailingZeros(bitGroup3); procedure.value(value); bitGroup3 &= ~(1L << value); } long bitGroup4 = this.bitGroup4; while (bitGroup4 != 0L) { byte value = (byte) Long.numberOfTrailingZeros(bitGroup4); procedure.value((byte) (value + 64)); bitGroup4 &= ~(1L << (byte) (value + 64)); } } @Override public ImmutableByteSet select(BytePredicate predicate) { MutableByteSet result = new ByteHashSet(); this.forEach(value -> { if (predicate.accept(value)) { result.add(value); } }); return result.toImmutable(); } @Override public ImmutableByteSet reject(BytePredicate predicate) { MutableByteSet result = new ByteHashSet(); this.forEach(value -> { if (!predicate.accept(value)) { result.add(value); } }); return result.toImmutable(); } @Override public <V> ImmutableSet<V> collect(ByteToObjectFunction<? extends V> function) { MutableSet<V> target = UnifiedSet.newSet(this.size()); this.forEach(each -> target.add(function.valueOf(each))); return target.toImmutable(); } @Override public byte detectIfNone(BytePredicate predicate, byte ifNone) { ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { byte nextByte = iterator.next(); if (predicate.accept(nextByte)) { return nextByte; } } return ifNone; } @Override public int count(BytePredicate predicate) { int count = 0; ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { if (predicate.accept(iterator.next())) { count++; } } return count; } @Override public boolean anySatisfy(BytePredicate predicate) { ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { if (predicate.accept(iterator.next())) { return true; } } return false; } @Override public boolean allSatisfy(BytePredicate predicate) { ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { if (!predicate.accept(iterator.next())) { return false; } } return true; } @Override public boolean noneSatisfy(BytePredicate predicate) { ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { if (predicate.accept(iterator.next())) { return false; } } return true; } @Override public MutableByteList toList() { return ByteArrayList.newList(this); } @Override public MutableByteSet toSet() { return ByteHashSet.newSet(this); } @Override public MutableByteBag toBag() { return ByteHashBag.newBag(this); } @Override public LazyByteIterable asLazy() { return new LazyByteIterableAdapter(this); } @Override public long sum() { long result = 0L; ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { result += iterator.next(); } return result; } @Override public byte max() { byte max = 0; if (this.bitGroup4 != 0L) { //the highest has to be from this max = (byte) (127 - Long.numberOfLeadingZeros(this.bitGroup4)); } else if (this.bitGroup3 != 0L) { max = (byte) (63 - Long.numberOfLeadingZeros(this.bitGroup3)); } else if (this.bitGroup2 != 0L) { max = (byte) ((Long.numberOfTrailingZeros(this.bitGroup2) + 1) * -1); } else if (this.bitGroup1 != 0L) { max = (byte) ((Long.numberOfTrailingZeros(this.bitGroup1) + 65) * -1); } return max; } @Override public byte maxIfEmpty(byte defaultValue) { return this.max(); } @Override public byte min() { byte min = 0; if (this.bitGroup1 != 0L) { //the minimum has to be from this min = (byte) (128 - Long.numberOfLeadingZeros(this.bitGroup1)); min *= -1; } else if (this.bitGroup2 != 0L) { min = (byte) ((64 - Long.numberOfLeadingZeros(this.bitGroup2)) * -1); } else if (this.bitGroup3 != 0L) { min = (byte) Long.numberOfTrailingZeros(this.bitGroup3); } else if (this.bitGroup4 != 0L) { min = (byte) (Long.numberOfTrailingZeros(this.bitGroup4) + 64); } return min; } @Override public byte minIfEmpty(byte defaultValue) { return this.min(); } @Override public double average() { return (double) this.sum() / (double) this.size(); } @Override public double median() { byte[] sortedArray = this.toSortedArray(); int middleIndex = sortedArray.length >> 1; if (sortedArray.length > 1 && (sortedArray.length & 1) == 0) { byte first = sortedArray[middleIndex]; byte second = sortedArray[middleIndex - 1]; return ((double) first + (double) second) / 2.0; } return (double) sortedArray[middleIndex]; } @Override public byte[] toSortedArray() { byte[] array = this.toArray(); Arrays.sort(array); return array; } @Override public MutableByteList toSortedList() { return ByteArrayList.newList(this).sortThis(); } @Override public <T> T injectInto(T injectedValue, ObjectByteToObjectFunction<? super T, ? extends T> function) { T result = injectedValue; ByteIterator iterator = this.byteIterator(); while (iterator.hasNext()) { result = function.valueOf(result, iterator.next()); } return result; } @Override public RichIterable<ByteIterable> chunk(int size) { if (size <= 0) { throw new IllegalArgumentException("Size for groups must be positive but was: " + size); } if (this.isEmpty()) { return Lists.mutable.empty(); } ByteIterator iterator = this.byteIterator(); MutableList<ByteIterable> result = Lists.mutable.empty(); while (iterator.hasNext()) { MutableByteSet batch = ByteSets.mutable.empty(); for (int i = 0; i < size && iterator.hasNext(); i++) { batch.add(iterator.next()); } result.add(batch); } return result; } @Override public ByteSet freeze() { return this; } @Override public ImmutableByteSet toImmutable() { return this; } private Object writeReplace() { return new ImmutableByteSetSerializationProxy(this); } private class InternalByteIterator implements ByteIterator { private int count; private byte minusOneTwentyEightToPlusOneTwentySeven = -128; @Override public boolean hasNext() { return this.count < ImmutableByteHashSet.this.size(); } @Override public byte next() { if (!this.hasNext()) { throw new NoSuchElementException("next() called, but the iterator is exhausted"); } this.count++; while (this.minusOneTwentyEightToPlusOneTwentySeven <= 127) { if (ImmutableByteHashSet.this.contains(this.minusOneTwentyEightToPlusOneTwentySeven)) { byte result = this.minusOneTwentyEightToPlusOneTwentySeven; this.minusOneTwentyEightToPlusOneTwentySeven++; return result; } this.minusOneTwentyEightToPlusOneTwentySeven++; } throw new NoSuchElementException("no more element, unexpected situation"); } } } private class MutableInternalByteIterator implements MutableByteIterator { private int count; private byte minusOneTwentyEightToPlusOneTwentySeven = -128; @Override public boolean hasNext() { return this.count < ByteHashSet.this.size(); } @Override public byte next() { if (!this.hasNext()) { throw new NoSuchElementException("next() called, but the iterator is exhausted"); } this.count++; while (this.minusOneTwentyEightToPlusOneTwentySeven <= 127) { if (ByteHashSet.this.contains(this.minusOneTwentyEightToPlusOneTwentySeven)) { byte result = this.minusOneTwentyEightToPlusOneTwentySeven; this.minusOneTwentyEightToPlusOneTwentySeven++; return result; } this.minusOneTwentyEightToPlusOneTwentySeven++; } throw new NoSuchElementException("no more element, unexpected situation"); } @Override public void remove() { if (this.count == 0 || !ByteHashSet.this.remove((byte) (this.minusOneTwentyEightToPlusOneTwentySeven - 1))) { throw new IllegalStateException(); } this.count--; } } }