Update FastUtilStackSetWrapper.java, HashStackSet.java, and 3 more files...
This commit is contained in:
parent
06a5e1c525
commit
bb89ca6bdb
@ -1,17 +1,25 @@
|
||||
package org.warp.commonutils.type;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
||||
import java.util.Collection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.warp.commonutils.error.IndexOutOfBoundsException;
|
||||
|
||||
public class FastUtilStackSetWrapper<T> implements StackSet<T> {
|
||||
public class FastUtilStackSetWrapper<T> implements StackSet<T>, Collection<T> {
|
||||
|
||||
private final AddStrategy addStrategy;
|
||||
private final ObjectLinkedOpenHashSet<T> linkedHashSet;
|
||||
|
||||
/**
|
||||
* The first element will be the head
|
||||
*/
|
||||
public FastUtilStackSetWrapper(ObjectLinkedOpenHashSet<T> linkedHashSet) {
|
||||
this(linkedHashSet, AddStrategy.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* The first element will be the head
|
||||
*/
|
||||
public FastUtilStackSetWrapper(ObjectLinkedOpenHashSet<T> linkedHashSet, AddStrategy addStrategy) {
|
||||
this.addStrategy = addStrategy;
|
||||
this.linkedHashSet = linkedHashSet;
|
||||
@ -21,17 +29,79 @@ public class FastUtilStackSetWrapper<T> implements StackSet<T> {
|
||||
public boolean push(T o) {
|
||||
switch (addStrategy) {
|
||||
case KEEP_POSITION:
|
||||
return linkedHashSet.add(o);
|
||||
if (linkedHashSet.contains(o)) {
|
||||
return false;
|
||||
}
|
||||
return linkedHashSet.addAndMoveToFirst(o);
|
||||
case OVERWRITE_POSITION:
|
||||
return linkedHashSet.addAndMoveToLast(o);
|
||||
return linkedHashSet.addAndMoveToFirst(o);
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unsupported strategy type: " + addStrategy);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public java.util.Iterator<T> iterator() {
|
||||
return linkedHashSet.iterator();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return linkedHashSet.toArray();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T1> T1[] toArray(@NotNull T1[] a) {
|
||||
//noinspection SuspiciousToArrayCall
|
||||
return linkedHashSet.toArray(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(T t) {
|
||||
return linkedHashSet.add(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return linkedHashSet.remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(@NotNull Collection<?> c) {
|
||||
return linkedHashSet.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(@NotNull Collection<? extends T> c) {
|
||||
return linkedHashSet.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(@NotNull Collection<?> c) {
|
||||
return linkedHashSet.removeAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(@NotNull Collection<?> c) {
|
||||
return linkedHashSet.retainAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
linkedHashSet.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T pop() {
|
||||
return linkedHashSet.removeLast();
|
||||
return linkedHashSet.removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return linkedHashSet.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -39,24 +109,27 @@ public class FastUtilStackSetWrapper<T> implements StackSet<T> {
|
||||
return linkedHashSet.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return linkedHashSet.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T top() {
|
||||
return linkedHashSet.last();
|
||||
return linkedHashSet.first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T peek(int i) {
|
||||
var size = linkedHashSet.size();
|
||||
int positionFromBottom = size - 1 - i;
|
||||
|
||||
if (positionFromBottom < 0 || positionFromBottom >= size) {
|
||||
throw new IndexOutOfBoundsException(positionFromBottom, 0, size);
|
||||
if (i < 0 || i >= size) {
|
||||
throw new IndexOutOfBoundsException(i, 0, size);
|
||||
}
|
||||
|
||||
var it = linkedHashSet.iterator();
|
||||
// Skip middle elements
|
||||
if (positionFromBottom > 0) {
|
||||
it.skip(positionFromBottom);
|
||||
if (i > 0) {
|
||||
it.skip(i);
|
||||
}
|
||||
return it.next();
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.warp.commonutils.type;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
||||
import java.util.Collection;
|
||||
|
||||
public class HashStackSet<T> extends FastUtilStackSetWrapper<T> {
|
||||
|
||||
@ -8,6 +9,10 @@ public class HashStackSet<T> extends FastUtilStackSetWrapper<T> {
|
||||
super(new ObjectLinkedOpenHashSet<>());
|
||||
}
|
||||
|
||||
public HashStackSet(Collection<T> collection) {
|
||||
super(new ObjectLinkedOpenHashSet<>(collection));
|
||||
}
|
||||
|
||||
public HashStackSet(AddStrategy addStrategy) {
|
||||
super(new ObjectLinkedOpenHashSet<>(), addStrategy);
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ public class JavaStackSetWrapper<T> implements StackSet<T> {
|
||||
|
||||
private final LinkedHashSet<T> linkedHashSet;
|
||||
|
||||
/**
|
||||
* The last element will be the head
|
||||
*/
|
||||
public JavaStackSetWrapper(LinkedHashSet<T> linkedHashSet) {
|
||||
this.linkedHashSet = linkedHashSet;
|
||||
}
|
||||
|
@ -1,59 +1,61 @@
|
||||
package org.warp.commonutils.type;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* {@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.
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/** Pops the top off the stack.
|
||||
/**
|
||||
* 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.
|
||||
/**
|
||||
* Checks whether the stack is empty.
|
||||
*
|
||||
* @return true if the stack is empty.
|
||||
*/
|
||||
|
||||
boolean isEmpty();
|
||||
|
||||
/** Peeks at the top of the stack (optional operation).
|
||||
/**
|
||||
* 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).
|
||||
/**
|
||||
* Peeks at an element on the stack (optional operation).
|
||||
*
|
||||
* <p>This default implementation just throws an {@link UnsupportedOperationException}.
|
||||
*
|
||||
@ -61,7 +63,6 @@ public interface StackSet<K> {
|
||||
* @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();
|
||||
}
|
||||
|
@ -117,6 +117,22 @@ public class TestStackSet {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStackSetCopyOrder() {
|
||||
for (StackSet<String> implementation : getImplementations()) {
|
||||
implementation.push("testBottom");
|
||||
implementation.push("testMiddle");
|
||||
implementation.push("testTop");
|
||||
if (implementation instanceof FastUtilStackSetWrapper) {
|
||||
var copy = new HashStackSet<>((FastUtilStackSetWrapper<String>) implementation);
|
||||
Assertions.assertEquals("testTop", copy.pop());
|
||||
Assertions.assertEquals("testMiddle", copy.pop());
|
||||
Assertions.assertEquals("testBottom", copy.pop());
|
||||
Assertions.assertTrue(copy.isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStackSetOneItemOnePop() {
|
||||
for (StackSet<String> implementation : getImplementations()) {
|
||||
|
Loading…
Reference in New Issue
Block a user