common-utils/src/main/java/org/warp/commonutils/type/StackSet.java

103 lines
2.7 KiB
Java

package org.warp.commonutils.type;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.NoSuchElementException;
import org.warp.commonutils.error.IndexOutOfBoundsException;
/**
* A stack but with the behavior of a Linked HashSet
*
* <p>A stack must provide the classical {@link #push(Object)} and
* {@link #pop()} operations, but may be also <em>peekable</em> to some extent: it may provide just the {@link #top()}
* function, or even a more powerful {@link #peek(int)} method that provides access to all elements on the stack
* (indexed from the top, which has index 0).
*/
public interface StackSet<K> {
/**
* Pushes the given object on the stack.
*
* @param o the object that will become the new top of the stack.
* @return true if added, false if already present
*/
boolean push(K o);
/**
* Pop multiple times
* @param count the number of times to pop
* @return list of popped elements
*/
default List<K> pop(int count) {
if (count < 0) {
throw new IndexOutOfBoundsException(count);
}
var items = new ArrayList<K>(count);
for (int i = 0; i < count; i++) {
items.add(this.pop());
}
return items;
}
/**
* Pops the top off the stack.
*
* @return the top of the stack.
* @throws NoSuchElementException if the stack is empty.
*/
K pop();
/**
* Checks whether the stack is empty.
*
* @return true if the stack is empty.
*/
boolean isEmpty();
/**
* Peeks at the top of the stack (optional operation).
*
* <p>This default implementation returns {@link #peek(int) peek(0)}.
*
* @return the top of the stack.
* @throws NoSuchElementException if the stack is empty.
*/
default K top() {
return peek(0);
}
/**
* Peeks at an element on the stack (optional operation).
*
* <p>This default implementation just throws an {@link UnsupportedOperationException}.
*
* @param i an index from the stop of the stack (0 represents the top).
* @return the {@code i}-th element on the stack.
* @throws IndexOutOfBoundsException if the designated element does not exist..
*/
default K peek(int i) {
throw new UnsupportedOperationException();
}
static <T> StackSet<T> create() {
return new HashStackSet<>();
}
static <T> StackSet<T> wrap(LinkedHashSet<T> linkedHashSet) {
return new JavaStackSetWrapper<>(linkedHashSet);
}
static <T> StackSet<T> wrap(ObjectLinkedOpenHashSet<T> linkedHashSet) {
return new FastUtilStackSetWrapper<>(linkedHashSet);
}
static <T> StackSet<T> wrap(ObjectLinkedOpenHashSet<T> linkedHashSet, AddStrategy addStrategy) {
return new FastUtilStackSetWrapper<>(linkedHashSet, addStrategy);
}
}