package org.warp.commonutils.type; import it.unimi.dsi.fastutil.objects.ObjectIterator; import it.unimi.dsi.fastutil.objects.ObjectIterators; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ObjectSet; import it.unimi.dsi.fastutil.objects.ObjectSets; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; import java.util.function.Consumer; import java.util.stream.Stream; import org.jetbrains.annotations.NotNull; public interface UnmodifiableSet extends UnmodifiableIterableSet { boolean contains(Object value); @NotNull ObjectIterator fastIterator(); void forEach(Consumer action); static UnmodifiableSet of(K[] values) { int valuesSize = (values != null) ? values.length : 0; if (valuesSize == 0) { // return mutable map return new EmptyUnmodifiableSet<>(); } return new MappedUnmodifiableSet<>(new ObjectOpenHashSet<>(values, 1.0f)); } static UnmodifiableSet of(Set set) { return new MappedUnmodifiableSet(set); } class EmptyUnmodifiableSet implements UnmodifiableSet { private EmptyUnmodifiableSet() {} @Override public int size() { return 0; } @Override public boolean isEmpty() { return true; } @Override public boolean contains(Object value) { return false; } @Override public void forEach(Consumer action) { } @NotNull @Override public Iterator iterator() { return new Iterator<>() { @Override public boolean hasNext() { return false; } @Override public K next() { throw new NoSuchElementException(); } }; } @NotNull @Override public ObjectIterator fastIterator() { return new ObjectIterator<>() { @Override public boolean hasNext() { return false; } @Override public K next() { throw new NoSuchElementException(); } }; } @Override public Set toUnmodifiableSet() { //noinspection unchecked return new HashSet<>(); } @Override public Stream stream() { return Stream.empty(); } @Override public UnmodifiableIterableMap toUnmodifiableIterableMapSetValues(V[] values) { return UnmodifiableIterableMap.of(null, values); } @Override public UnmodifiableIterableMap toUnmodifiableIterableMapSetKeys(K2[] keys) { return UnmodifiableIterableMap.of(keys, null); } @Override public UnmodifiableMap toUnmodifiableMapSetValues(V[] values) { return UnmodifiableMap.of(null, values); } @Override public UnmodifiableMap toUnmodifiableMapSetKeys(K2[] keys) { return UnmodifiableMap.of(keys, null); } } class MappedUnmodifiableSet implements UnmodifiableSet { private final Set set; private MappedUnmodifiableSet(@NotNull Set set) { this.set = set; } @Override public int size() { return set.size(); } @Override public boolean isEmpty() { return set.isEmpty(); } @Override public boolean contains(Object key) { //noinspection SuspiciousMethodCalls return set.contains(key); } @Override public void forEach(Consumer action) { set.forEach(action); } @Override public Set toUnmodifiableSet() { return Collections.unmodifiableSet(set); } @NotNull @Override public Iterator iterator() { return set.iterator(); } @NotNull @Override public ObjectIterator fastIterator() { if (set instanceof ObjectSet) { return ((ObjectSet) set).iterator(); } else { return ObjectIterators.asObjectIterator(set.iterator()); } } @Override public Stream stream() { return set.stream(); } @Override public UnmodifiableIterableMap toUnmodifiableIterableMapSetValues(V[] values) { return UnmodifiableIterableMap.ofObjects(set.toArray(), values); } @Override public UnmodifiableIterableMap toUnmodifiableIterableMapSetKeys(K2[] keys) { return UnmodifiableIterableMap.ofObjects(keys, set.toArray()); } @Override public UnmodifiableMap toUnmodifiableMapSetValues(V[] values) { return UnmodifiableMap.ofObjects(set.toArray(), values); } @Override public UnmodifiableMap toUnmodifiableMapSetKeys(K2[] keys) { return UnmodifiableMap.ofObjects(keys, set.toArray()); } } }