collections.immutable.HashSet23 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of collections Show documentation
Show all versions of collections Show documentation
Java code for the collections package.
The newest version!
package collections.immutable;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
import java.util.Spliterator;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.granitesoft.requirement.Requirements;
//
//Represents a hashset as a list of elements ordered by their hash.
//This is different than a standard hashset in that lookup's are O(log n).
//Therefore the only advantage of HashSet23 over TreeMap23 is that you can use
//elements for which a comparator is not trivial.
//
final class HashSet23 implements ImmSet {
final TreeList23 elements;
HashSet23(final TreeList23 elements) {
assert elements != null;
this.elements = elements;
}
static HashSet23 singleton(final E element) {
return new HashSet23(TreeList23.singleton(element));
}
static HashSet23 empty() {
return new HashSet23(TreeList23.empty());
}
static HashSet23 of(final Iterable extends E> elements) {
return new HashSet23(TreeList23.ofSortedUnique(HashSet23::compare, elements));
}
@Override
public int size() {
return elements.size();
}
@Override
public boolean contains(final E element) {
return elements.getIndexOf(e -> compare(element, e)) >= 0;
}
@Override
public HashSet23 add(final E element) {
return contains(element) ? this : new HashSet23<>(elements.insertAt(elements.naturalPosition(e -> compare(element, e)), element));
}
@Override
public HashSet23 union(final ImmSet other) {
Requirements.require(other, Requirements.notNull(), () -> "other");
HashSet23 s = this;
for(E e: other) {
s = s.add(e);
}
return s;
}
@Override
public HashSet23 remove(final E element) {
final int index = elements.getIndexOf(e -> compare(element, e));
return index < 0 ? this : new HashSet23<>(elements.removeAt(index));
}
@Override
public HashSet23 filter(final Predicate filter) {
Requirements.require(filter, Requirements.notNull(), () -> "filter");
return new HashSet23<>(elements.filter(filter));
}
@Override
public HashSet23 retain(final Iterable extends E> other) {
final HashSet23 hs = HashSet23.of(Requirements.require(other, Requirements.notNull(), () -> "other"));
return filter(hs::contains);
}
@Override
public HashSet23 removeAllIn(final Iterable extends E> other) {
Requirements.require(other, Requirements.notNull(), () -> "other");
HashSet23 m = this;
for(E e: other) {
m = m.remove(e);
}
return m;
}
@Override
public Set asCollection() {
return new Set23Set<>(this);
}
@Override
public int hashCode() {
return asCollection().hashCode();
}
@Override
public boolean equals(final Object otherObject) {
if (!(otherObject instanceof ImmSet)) {
return false;
}
final ImmSet> other = (ImmSet>)otherObject;
return asCollection().equals(other.asCollection());
}
@Override
public String toString() {
return asCollection().toString();
}
@Override
public Iterator iterator() {
return elements.iterator();
}
@Override
public Spliterator spliterator() {
return elements.spliterator();
}
@Override
public Stream stream() {
return StreamSupport.stream(spliterator(), false);
}
static int compare(final E a, final E b) {
int cmp = Integer.compare(Objects.hash(a), Objects.hash(b));
if (cmp != 0) {
return cmp;
}
if (Objects.equals(a, b)) {
return 0;
}
return Integer.compare(System.identityHashCode(a), System.identityHashCode(b));
}
}