All Downloads are FREE. Search and download functionalities are using the official Maven repository.

collections.immutable.HashSet23 Maven / Gradle / Ivy

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 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 other) {
        final HashSet23 hs = HashSet23.of(Requirements.require(other, Requirements.notNull(), () -> "other"));
        return filter(hs::contains);
    }

    @Override
    public HashSet23 removeAllIn(final Iterable 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));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy