blob: 7e9172da91293803dae4f98eac39d9d4a6174547 [file] [log] [blame]
package org.checkerframework.dataflow.util;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
/** A set that is more efficient than HashSet for 0 and 1 elements. */
public final class MostlySingleton<T> implements Set<T> {
private enum State {
EMPTY,
SINGLETON,
ANY
}
private State state = State.EMPTY;
private T value;
private HashSet<T> set;
@Override
public int size() {
switch (state) {
case EMPTY:
return 0;
case SINGLETON:
return 1;
case ANY:
return set.size();
default:
throw new AssertionError();
}
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public boolean contains(Object o) {
switch (state) {
case EMPTY:
return false;
case SINGLETON:
return Objects.equals(o, value);
case ANY:
return set.contains(o);
default:
throw new AssertionError();
}
}
@Override
@SuppressWarnings("fallthrough")
public boolean add(T e) {
switch (state) {
case EMPTY:
state = State.SINGLETON;
value = e;
return true;
case SINGLETON:
state = State.ANY;
set = new HashSet<T>();
set.add(value);
value = null;
// fallthrough
case ANY:
return set.add(e);
default:
throw new AssertionError();
}
}
@Override
public Iterator<T> iterator() {
switch (state) {
case EMPTY:
return Collections.emptyIterator();
case SINGLETON:
return new Iterator<T>() {
private boolean hasNext = true;
@Override
public boolean hasNext() {
return hasNext;
}
@Override
public T next() {
if (hasNext) {
hasNext = false;
return value;
}
throw new NoSuchElementException();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
case ANY:
return set.iterator();
default:
throw new AssertionError();
}
}
@Override
public Object[] toArray() {
throw new UnsupportedOperationException();
}
@Override
public <S> S[] toArray(S[] a) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
public boolean containsAll(Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean addAll(Collection<? extends T> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
}