
org.javimmutable.collections.common.AbstractJImmutableSetUsingMap Maven / Gradle / Ivy
package org.javimmutable.collections.common;
import org.javimmutable.collections.JImmutableMap;
import org.javimmutable.collections.JImmutableSet;
import org.javimmutable.collections.SplitableIterator;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Iterator;
import java.util.Set;
public abstract class AbstractJImmutableSetUsingMap
extends AbstractJImmutableSet
{
protected final JImmutableMap map;
public AbstractJImmutableSetUsingMap(@Nonnull JImmutableMap map)
{
this.map = map;
}
@Override
@Nonnull
public JImmutableSet insert(@Nonnull T value)
{
final JImmutableMap newMap = map.assign(value, Boolean.TRUE);
return (newMap != map) ? create(newMap) : this;
}
@Override
public boolean contains(@Nullable T value)
{
return (value != null) && map.getValueOr(value, Boolean.FALSE);
}
@Nonnull
@Override
public JImmutableSet delete(T value)
{
JImmutableMap newMap = map.delete(value);
return (newMap != map) ? create(newMap) : this;
}
@Nonnull
@Override
public JImmutableSet deleteAll(@Nonnull Iterator extends T> values)
{
JImmutableMap newMap = map;
while (values.hasNext()) {
final T value = values.next();
if (value != null) {
newMap = newMap.delete(value);
}
}
return (newMap != map) ? create(newMap) : this;
}
@Nonnull
@Override
public JImmutableSet union(@Nonnull Iterator extends T> values)
{
JImmutableMap newMap = map;
while (values.hasNext()) {
final T value = values.next();
if (value != null) {
newMap = newMap.assign(value, Boolean.TRUE);
}
}
return (newMap != map) ? create(newMap) : this;
}
@Nonnull
@Override
public JImmutableSet intersection(@Nonnull Iterator extends T> values)
{
if (isEmpty()) {
return this;
}
if (!values.hasNext()) {
return deleteAll();
}
Set otherSet = emptyMutableSet();
while (values.hasNext()) {
final T value = values.next();
if (value != null) {
otherSet.add(value);
}
}
JImmutableMap newMap = map;
for (JImmutableMap.Entry entry : map) {
if (!otherSet.contains(entry.getKey())) {
newMap = newMap.delete(entry.getKey());
}
}
return (newMap != map) ? create(newMap) : this;
}
@Nonnull
@Override
public JImmutableSet intersection(@Nonnull Set extends T> other)
{
if (isEmpty()) {
return this;
} else if (other.isEmpty()) {
return deleteAll();
} else {
JImmutableMap newMap = map;
for (T value : map.keys()) {
if (!other.contains(value)) {
newMap = newMap.delete(value);
}
}
return (newMap != map) ? create(newMap) : this;
}
}
@Override
public int size()
{
return map.size();
}
@Override
public boolean isEmpty()
{
return map.isEmpty();
}
@Nonnull
@Override
public SplitableIterator iterator()
{
return map.keys().iterator();
}
@Override
public int getSpliteratorCharacteristics()
{
return map.keys().getSpliteratorCharacteristics();
}
@Override
public void checkInvariants()
{
checkSetInvariants();
}
protected void checkSetInvariants()
{
map.checkInvariants();
for (JImmutableMap.Entry entry : map) {
if (!entry.getValue()) {
throw new RuntimeException();
}
}
}
/**
* Implemented by derived classes to create a new instance of the appropriate class.
*/
protected abstract JImmutableSet create(JImmutableMap map);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy