All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.ajjpj.abase.collection.immutable.AHashSet Maven / Gradle / Ivy
Go to download
a-base is a library of basic (hence the name) classes, most notably immutable collection classes with copy-on-write operations
package com.ajjpj.abase.collection.immutable;
import com.ajjpj.abase.collection.ACollectionHelper;
import com.ajjpj.abase.collection.AEquality;
import com.ajjpj.abase.collection.AEqualsWrapper;
import com.ajjpj.abase.function.AFunction1;
import com.ajjpj.abase.function.APredicate;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
/**
* This is an immutable hash set implementation. It has mutator methods that return a modified copy of the set. It
* does not implement java.util.Set
because that interface is inherently mutable. It does however
* provide a method to return an immutable view implementing java.util.Set
.
*
* It provides uniqueness guarantees based on a configurable equality strategy which defaults to "equals-based".
*
* @author arno
*/
public class AHashSet implements ACollection> {
private final AHashMap inner;
private static final AHashSet emptyEquals = new AHashSet<>(AHashMap.empty(AEquality.EQUALS));
private static final AHashSet emptyIdentity = new AHashSet<>(AHashMap.empty(AEquality.IDENTITY));
/**
* Returns an empty AHashSet instance with default (i.e. equals-based) equality. Using a factory method instead of
* a constructor allows AHashSet to return a cached implementation.
*/
@SuppressWarnings("unchecked")
public static AHashSet empty() {
return (AHashSet) emptyEquals;
}
/**
* Returns an empty AHashSet instance with a given equality strategy. Using a factory method instead of
* a constructor allows AHashSet to return a cached implementation.
*/
@SuppressWarnings("unchecked")
public static AHashSet empty(AEquality equality) {
if(equality == AEquality.EQUALS) return (AHashSet) emptyEquals;
if(equality == AEquality.IDENTITY) return (AHashSet) emptyIdentity;
return new AHashSet<>(AHashMap.empty(equality));
}
/**
* Creates an AHashSet instance with default (i.e. equals-based) equality that is initialized with the elements from a given collection.
*/
public static AHashSet create(Iterable elements) {
return create(AEquality.EQUALS, elements);
}
/**
* Creates an AHashSet instance with a given equality strategy that is initialized with the elements from a given collection.
*/
public static AHashSet create(AEquality equality, Iterable elements) {
AHashSet result = empty(equality);
for(T el: elements) {
result = result.added(el);
}
return result;
}
/**
* Creates an AHashSet instance with default (i.e. equals-based) equality that is initialized with the elements from a given collection.
*/
public static AHashSet create(T... elements) {
return create(AEquality.EQUALS, elements);
}
/**
* Creates an AHashSet instance with a given equality strategy that is initialized with the elements from a given collection.
*/
public static AHashSet create(AEquality equality, T... elements) {
AHashSet result = empty(equality);
for(T el: elements) {
result = result.added(el);
}
return result;
}
private AHashSet(AHashMap inner) {
this.inner = inner;
}
public int size() {
return inner.size();
}
public boolean isEmpty() {
return inner.isEmpty();
}
public boolean nonEmpty() {
return inner.nonEmpty();
}
public boolean contains(T el) {
return inner.containsKey(el);
}
/**
* This method creates and returns a new AHashSet instance that is guaranteed to contain the given new element.
* 'Containment' is relative to the configured equality strategy - if e.g. the set uses AEquality.IDENTITY, it
* can contain two objects that are equal without being the same.
*
* This is the only method to add elements to the set.
*/
public AHashSet added(T el) {
final AHashMap newInner = inner.updated(el, true);
if(newInner == inner) {
return this;
}
return new AHashSet<> (newInner);
}
/**
* This method creates and returns a new AHashSet instance that is guaranteed not to contain the given element.
* 'Containment' is relative to the configured equality strategy - if e.g. the set uses AEquality.IDENTITY, it
* might not remove an element that is equal to the object that is passed to the removed()
method
* if they are not the same.
*
* This is the only method to remove elements from the set.
*/
public AHashSet removed(T el) {
final AHashMap newInner = inner.removed(el);
if(newInner == inner) {
return this;
}
return new AHashSet<> (newInner);
}
/**
* Returns a read-only java.util.Set
view of this set. The view is read-through, and creation has
* constant time complexity.
*/
public java.util.Set asJavaUtilSet() {
return inner.asJavaUtilMap().keySet();
}
@Override
public Iterator iterator() {
return asJavaUtilSet().iterator();
}
@Override
public int hashCode() {
return inner.hashCode();
}
@SuppressWarnings("SimplifiableIfStatement")
@Override
public boolean equals(Object o) {
if(o == this) {
return true;
}
if(! (o instanceof AHashSet)) {
return false;
}
return inner.equals(((AHashSet)o).inner);
}
public AList toList() {
return AList.create(this);
}
@Override public String mkString() {
return ACollectionHelper.mkString(this);
}
@Override public String mkString(String prefix, String separator, String suffix) {
return ACollectionHelper.mkString(this, prefix, separator, suffix);
}
@Override public String mkString(String separator) {
return ACollectionHelper.mkString(this, separator);
}
@Override public boolean forAll(APredicate pred) throws E { //TODO junit test
return ACollectionHelper.forAll(this, pred);
}
@Override public boolean exists(APredicate pred) throws E { //TODO junit
return ACollectionHelper.exists(this, pred);
}
@Override public AHashSet toSet() {
return this;
}
@Override public AHashSet toSet(AEquality equality) {
if(equality == inner.equality) {
return this;
}
return AHashSet.create(equality, this);
}
@Override public AOption find(APredicate pred) throws E {
return ACollectionHelper.find(this, pred);
}
@Override public AHashSet map(AFunction1 f) throws E {
// list instead of set to support arbitrary equality implementations
return create(inner.equality, ACollectionHelper.map(this, f));
}
@Override public AFilterMonadic> flatMap(AFunction1, T, E> f) throws E {
return create(inner.equality, ACollectionHelper.flatMap(this, f));
}
@SuppressWarnings("unchecked")
@Override public AHashSet flatten() {
return (AHashSet) create(inner.equality, ACollectionHelper.flatten((Iterable extends Iterable>) this));
}
@Override public AHashSet filter(APredicate pred) throws E {
return create(inner.equality, ACollectionHelper.filter(this, pred));
}
@Override public AMap> groupBy(AFunction1 f) throws E { //TODO javadoc: *equals* based (and *not* the same as here!)
return groupBy(f, AEquality.EQUALS);
}
@Override public AMap> groupBy(AFunction1 f, AEquality keyEquality) throws E {
final Map, Collection> raw = ACollectionHelper.groupBy(this, f, keyEquality);
AMap> result = AHashMap.empty(keyEquality);
for(Map.Entry, Collection> entry: raw.entrySet()) {
result = result.updated(entry.getKey().value, AHashSet.create(entry.getValue()));
}
return result;
}
}