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;
|
package org.warp.commonutils.type;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
||||||
|
import java.util.Collection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.warp.commonutils.error.IndexOutOfBoundsException;
|
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 AddStrategy addStrategy;
|
||||||
private final ObjectLinkedOpenHashSet<T> linkedHashSet;
|
private final ObjectLinkedOpenHashSet<T> linkedHashSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The first element will be the head
|
||||||
|
*/
|
||||||
public FastUtilStackSetWrapper(ObjectLinkedOpenHashSet<T> linkedHashSet) {
|
public FastUtilStackSetWrapper(ObjectLinkedOpenHashSet<T> linkedHashSet) {
|
||||||
this(linkedHashSet, AddStrategy.getDefault());
|
this(linkedHashSet, AddStrategy.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The first element will be the head
|
||||||
|
*/
|
||||||
public FastUtilStackSetWrapper(ObjectLinkedOpenHashSet<T> linkedHashSet, AddStrategy addStrategy) {
|
public FastUtilStackSetWrapper(ObjectLinkedOpenHashSet<T> linkedHashSet, AddStrategy addStrategy) {
|
||||||
this.addStrategy = addStrategy;
|
this.addStrategy = addStrategy;
|
||||||
this.linkedHashSet = linkedHashSet;
|
this.linkedHashSet = linkedHashSet;
|
||||||
@ -21,17 +29,79 @@ public class FastUtilStackSetWrapper<T> implements StackSet<T> {
|
|||||||
public boolean push(T o) {
|
public boolean push(T o) {
|
||||||
switch (addStrategy) {
|
switch (addStrategy) {
|
||||||
case KEEP_POSITION:
|
case KEEP_POSITION:
|
||||||
return linkedHashSet.add(o);
|
if (linkedHashSet.contains(o)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return linkedHashSet.addAndMoveToFirst(o);
|
||||||
case OVERWRITE_POSITION:
|
case OVERWRITE_POSITION:
|
||||||
return linkedHashSet.addAndMoveToLast(o);
|
return linkedHashSet.addAndMoveToFirst(o);
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unsupported strategy type: " + addStrategy);
|
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
|
@Override
|
||||||
public T pop() {
|
public T pop() {
|
||||||
return linkedHashSet.removeLast();
|
return linkedHashSet.removeFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return linkedHashSet.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -39,24 +109,27 @@ public class FastUtilStackSetWrapper<T> implements StackSet<T> {
|
|||||||
return linkedHashSet.isEmpty();
|
return linkedHashSet.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
return linkedHashSet.contains(o);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T top() {
|
public T top() {
|
||||||
return linkedHashSet.last();
|
return linkedHashSet.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T peek(int i) {
|
public T peek(int i) {
|
||||||
var size = linkedHashSet.size();
|
var size = linkedHashSet.size();
|
||||||
int positionFromBottom = size - 1 - i;
|
if (i < 0 || i >= size) {
|
||||||
|
throw new IndexOutOfBoundsException(i, 0, size);
|
||||||
if (positionFromBottom < 0 || positionFromBottom >= size) {
|
|
||||||
throw new IndexOutOfBoundsException(positionFromBottom, 0, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var it = linkedHashSet.iterator();
|
var it = linkedHashSet.iterator();
|
||||||
// Skip middle elements
|
// Skip middle elements
|
||||||
if (positionFromBottom > 0) {
|
if (i > 0) {
|
||||||
it.skip(positionFromBottom);
|
it.skip(i);
|
||||||
}
|
}
|
||||||
return it.next();
|
return it.next();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.warp.commonutils.type;
|
package org.warp.commonutils.type;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
public class HashStackSet<T> extends FastUtilStackSetWrapper<T> {
|
public class HashStackSet<T> extends FastUtilStackSetWrapper<T> {
|
||||||
|
|
||||||
@ -8,6 +9,10 @@ public class HashStackSet<T> extends FastUtilStackSetWrapper<T> {
|
|||||||
super(new ObjectLinkedOpenHashSet<>());
|
super(new ObjectLinkedOpenHashSet<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HashStackSet(Collection<T> collection) {
|
||||||
|
super(new ObjectLinkedOpenHashSet<>(collection));
|
||||||
|
}
|
||||||
|
|
||||||
public HashStackSet(AddStrategy addStrategy) {
|
public HashStackSet(AddStrategy addStrategy) {
|
||||||
super(new ObjectLinkedOpenHashSet<>(), addStrategy);
|
super(new ObjectLinkedOpenHashSet<>(), addStrategy);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,9 @@ public class JavaStackSetWrapper<T> implements StackSet<T> {
|
|||||||
|
|
||||||
private final LinkedHashSet<T> linkedHashSet;
|
private final LinkedHashSet<T> linkedHashSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last element will be the head
|
||||||
|
*/
|
||||||
public JavaStackSetWrapper(LinkedHashSet<T> linkedHashSet) {
|
public JavaStackSetWrapper(LinkedHashSet<T> linkedHashSet) {
|
||||||
this.linkedHashSet = linkedHashSet;
|
this.linkedHashSet = linkedHashSet;
|
||||||
}
|
}
|
||||||
|
@ -1,59 +1,61 @@
|
|||||||
package org.warp.commonutils.type;
|
package org.warp.commonutils.type;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A stack but with the behavior of a Linked HashSet
|
* A stack but with the behavior of a Linked HashSet
|
||||||
*
|
*
|
||||||
* <p>A stack must provide the classical {@link #push(Object)} and
|
* <p>A stack must provide the classical {@link #push(Object)} and
|
||||||
* {@link #pop()} operations, but may be also <em>peekable</em>
|
* {@link #pop()} operations, but may be also <em>peekable</em> to some extent: it may provide just the {@link #top()}
|
||||||
* to some extent: it may provide just the {@link #top()} function,
|
* function, or even a more powerful {@link #peek(int)} method that provides access to all elements on the stack
|
||||||
* or even a more powerful {@link #peek(int)} method that provides
|
* (indexed from the top, which has index 0).
|
||||||
* access to all elements on the stack (indexed from the top, which
|
|
||||||
* has index 0).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public interface StackSet<K> {
|
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.
|
* @param o the object that will become the new top of the stack.
|
||||||
* @return true if added, false if already present
|
* @return true if added, false if already present
|
||||||
*/
|
*/
|
||||||
|
|
||||||
boolean push(K o);
|
boolean push(K o);
|
||||||
|
|
||||||
/** Pops the top off the stack.
|
/**
|
||||||
|
* Pops the top off the stack.
|
||||||
*
|
*
|
||||||
* @return the top of the stack.
|
* @return the top of the stack.
|
||||||
* @throws NoSuchElementException if the stack is empty.
|
* @throws NoSuchElementException if the stack is empty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
K pop();
|
K pop();
|
||||||
|
|
||||||
/** Checks whether the stack is empty.
|
/**
|
||||||
|
* Checks whether the stack is empty.
|
||||||
*
|
*
|
||||||
* @return true if the stack is empty.
|
* @return true if the stack is empty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
boolean isEmpty();
|
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)}.
|
* <p>This default implementation returns {@link #peek(int) peek(0)}.
|
||||||
*
|
*
|
||||||
* @return the top of the stack.
|
* @return the top of the stack.
|
||||||
* @throws NoSuchElementException if the stack is empty.
|
* @throws NoSuchElementException if the stack is empty.
|
||||||
*/
|
*/
|
||||||
|
default K top() {
|
||||||
default K top() {
|
|
||||||
return peek(0);
|
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}.
|
* <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.
|
* @return the {@code i}-th element on the stack.
|
||||||
* @throws IndexOutOfBoundsException if the designated element does not exist..
|
* @throws IndexOutOfBoundsException if the designated element does not exist..
|
||||||
*/
|
*/
|
||||||
|
|
||||||
default K peek(int i) {
|
default K peek(int i) {
|
||||||
throw new UnsupportedOperationException();
|
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
|
@Test
|
||||||
public void testStackSetOneItemOnePop() {
|
public void testStackSetOneItemOnePop() {
|
||||||
for (StackSet<String> implementation : getImplementations()) {
|
for (StackSet<String> implementation : getImplementations()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user