package org.warp.commonutils.type; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ObjectSets; import java.util.Collections; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; import java.util.function.Consumer; import java.util.function.IntFunction; import org.jetbrains.annotations.NotNull; public interface UnmodifiableIterableSet extends Iterable { int size(); boolean isEmpty(); void forEach(Consumer action); Set toUnmodifiableSet(); UnmodifiableIterableMap toUnmodifiableIterableMapSetValues(V[] values); UnmodifiableIterableMap toUnmodifiableIterableMapSetKeys(K2[] keys); UnmodifiableMap toUnmodifiableMapSetValues(V[] values); UnmodifiableMap toUnmodifiableMapSetKeys(K2[] keys); static UnmodifiableIterableSet of(K[] items) { int keysSize = (items != null) ? items.length : 0; if (keysSize == 0) { // return mutable map return new UnmodifiableIterableSet() { @NotNull @Override public Iterator iterator() { return new Iterator<>() { @Override public boolean hasNext() { return false; } @Override public K next() { throw new NoSuchElementException(); } }; } @Override public int size() { return 0; } @Override public boolean isEmpty() { return true; } @Override public void forEach(Consumer action) {} @Override public Set toUnmodifiableSet() { //noinspection unchecked return ObjectSets.EMPTY_SET; } @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); } }; } return new UnmodifiableIterableSet() { @Override public int size() { return keysSize; } @Override public boolean isEmpty() { return false; } @Override public void forEach(Consumer action) { for (int i = 0; i < items.length; i++) { action.accept(items[i]); } } @Override public Set toUnmodifiableSet() { return ObjectSets.unmodifiable(new ObjectOpenHashSet<>(items, 1.0f)); } @Override public UnmodifiableIterableMap toUnmodifiableIterableMapSetValues(V[] values) { return UnmodifiableIterableMap.of(items, values); } @Override public UnmodifiableIterableMap toUnmodifiableIterableMapSetKeys(K2[] keys) { return UnmodifiableIterableMap.of(keys, items); } @Override public UnmodifiableMap toUnmodifiableMapSetValues(V[] values) { return UnmodifiableMap.of(items, values); } @Override public UnmodifiableMap toUnmodifiableMapSetKeys(K2[] keys) { return UnmodifiableMap.of(keys, items); } @NotNull @Override public Iterator iterator() { return new ObjectOpenHashSet(items, 1.0f).iterator(); } }; } static UnmodifiableIterableSet of(Set items, IntFunction generator) { return new UnmodifiableIterableSet() { @Override public int size() { return items.size(); } @Override public boolean isEmpty() { return items.isEmpty(); } @Override public void forEach(Consumer action) { items.forEach(action); } @Override public Set toUnmodifiableSet() { return Collections.unmodifiableSet(items); } @Override public UnmodifiableIterableMap toUnmodifiableIterableMapSetValues(V[] values) { return UnmodifiableIterableMap.of(items.toArray(generator), values); } @Override public UnmodifiableIterableMap toUnmodifiableIterableMapSetKeys(K2[] keys) { return UnmodifiableIterableMap.of(keys, items.toArray(generator)); } @Override public UnmodifiableMap toUnmodifiableMapSetValues(V[] values) { return UnmodifiableMap.of(items.toArray(generator), values); } @Override public UnmodifiableMap toUnmodifiableMapSetKeys(K2[] keys) { return UnmodifiableMap.of(keys, items.toArray(generator)); } @NotNull @Override public Iterator iterator() { return items.iterator(); } }; } }