org.semanticweb.owlapi.util.SmallSet Maven / Gradle / Ivy
package org.semanticweb.owlapi.util;
import static org.semanticweb.owlapi.util.OWLAPIPreconditions.checkNotNull;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.stream.Stream;
import javax.annotation.Nullable;
/**
* This class provides a compact implementation of a very small sets - less than
* or equal to three elements
*
* @param
* set element type
*/
public class SmallSet extends AbstractSet {
T element1;
T element2;
T element3;
/**
* @param collection
* collection to copy
*/
public SmallSet(Collection collection) {
if (collection.size() > 3) {
throw new IllegalArgumentException(
"Trying to create a small set with too many elements - max 3, requested: " + collection.size());
}
for (T t : collection) {
add(t);
}
}
@Override
public boolean add(@Nullable T t) {
checkNotNull(t, "SmallSet cannot store null values");
if (contains(t)) {
return false;
}
if (element1 == null) {
element1 = t;
return true;
} else if (element2 == null) {
element2 = t;
return true;
} else if (element3 == null) {
element3 = t;
return true;
} else {
throw new IllegalStateException("cannot store more than 3 elements in a small set");
}
}
@Override
public boolean remove(@Nullable Object o) {
if (o == null) {
return false;
}
int oHash = o.hashCode();
if (checkMatch(o, oHash, element1)) {
element1 = null;
return true;
} else if (checkMatch(o, oHash, element2)) {
element2 = null;
return true;
} else if (checkMatch(o, oHash, element3)) {
element3 = null;
return true;
} else {
return false;
}
}
@Override
public boolean contains(@Nullable Object o) {
if (o == null) {
return false;
}
int oHash = o.hashCode();
return checkMatch(o, oHash, element1) || checkMatch(o, oHash, element2) || checkMatch(o, oHash, element3);
}
protected boolean checkMatch(Object o, int oHash, @Nullable T element) {
return element != null && oHash == element.hashCode() && o.equals(element);
}
@Override
public Iterator iterator() {
return new Iterator() {
int cp = 1;
@Override
public void remove() {
throw new UnsupportedOperationException("remove");
}
@Override
public boolean hasNext() {
switch (cp) {
case 1:
if (element1 != null) {
return true;
} else {
cp++;
}
//$FALL-THROUGH$
case 2:
if (element2 != null) {
return true;
} else {
cp++;
}
//$FALL-THROUGH$
case 3:
if (element3 != null) {
return true;
} else {
cp++;
}
//$FALL-THROUGH$
default:
return false;
}
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException("No Next Element");
}
switch (cp++) {
case 1:
return element1;
case 2:
return element2;
case 3:
return element3;
default:
throw new IllegalStateException("Iterator pointing past end of virtual array");
}
}
};
}
@Override
public Stream stream() {
Stream stream = Stream.empty();
if (element1 != null) {
stream = Stream.of(element1);
}
if (element2 != null) {
stream = Stream.concat(stream, Stream.of(element2));
}
if (element3 != null) {
stream = Stream.concat(stream, Stream.of(element3));
}
return stream;
}
@Override
public int size() {
int count = 0;
if (element1 != null) {
count++;
}
if (element2 != null) {
count++;
}
if (element3 != null) {
count++;
}
return count;
}
@Override
public String toString() {
return String.format("#", element1, element2, element3);
}
}