From bb89ca6bdb72608f1869e8c2bb0fd35eb8a8d87a Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Mon, 14 Dec 2020 00:41:55 +0100 Subject: [PATCH] Update FastUtilStackSetWrapper.java, HashStackSet.java, and 3 more files... --- .../type/FastUtilStackSetWrapper.java | 95 ++++++++++++++++--- .../warp/commonutils/type/HashStackSet.java | 5 + .../commonutils/type/JavaStackSetWrapper.java | 3 + .../org/warp/commonutils/type/StackSet.java | 33 +++---- .../warp/commonutils/type/TestStackSet.java | 16 ++++ 5 files changed, 125 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/warp/commonutils/type/FastUtilStackSetWrapper.java b/src/main/java/org/warp/commonutils/type/FastUtilStackSetWrapper.java index d4e57da..9c1ba32 100644 --- a/src/main/java/org/warp/commonutils/type/FastUtilStackSetWrapper.java +++ b/src/main/java/org/warp/commonutils/type/FastUtilStackSetWrapper.java @@ -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 implements StackSet { +public class FastUtilStackSetWrapper implements StackSet, Collection { private final AddStrategy addStrategy; private final ObjectLinkedOpenHashSet linkedHashSet; + /** + * The first element will be the head + */ public FastUtilStackSetWrapper(ObjectLinkedOpenHashSet linkedHashSet) { this(linkedHashSet, AddStrategy.getDefault()); } + /** + * The first element will be the head + */ public FastUtilStackSetWrapper(ObjectLinkedOpenHashSet linkedHashSet, AddStrategy addStrategy) { this.addStrategy = addStrategy; this.linkedHashSet = linkedHashSet; @@ -21,17 +29,79 @@ public class FastUtilStackSetWrapper implements StackSet { 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 iterator() { + return linkedHashSet.iterator(); + } + + @NotNull + @Override + public Object[] toArray() { + return linkedHashSet.toArray(); + } + + @NotNull + @Override + public 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 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 implements StackSet { 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(); } diff --git a/src/main/java/org/warp/commonutils/type/HashStackSet.java b/src/main/java/org/warp/commonutils/type/HashStackSet.java index 44c2d84..8472fee 100644 --- a/src/main/java/org/warp/commonutils/type/HashStackSet.java +++ b/src/main/java/org/warp/commonutils/type/HashStackSet.java @@ -1,6 +1,7 @@ package org.warp.commonutils.type; import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; +import java.util.Collection; public class HashStackSet extends FastUtilStackSetWrapper { @@ -8,6 +9,10 @@ public class HashStackSet extends FastUtilStackSetWrapper { super(new ObjectLinkedOpenHashSet<>()); } + public HashStackSet(Collection collection) { + super(new ObjectLinkedOpenHashSet<>(collection)); + } + public HashStackSet(AddStrategy addStrategy) { super(new ObjectLinkedOpenHashSet<>(), addStrategy); } diff --git a/src/main/java/org/warp/commonutils/type/JavaStackSetWrapper.java b/src/main/java/org/warp/commonutils/type/JavaStackSetWrapper.java index d642f18..0e556bd 100644 --- a/src/main/java/org/warp/commonutils/type/JavaStackSetWrapper.java +++ b/src/main/java/org/warp/commonutils/type/JavaStackSetWrapper.java @@ -8,6 +8,9 @@ public class JavaStackSetWrapper implements StackSet { private final LinkedHashSet linkedHashSet; + /** + * The last element will be the head + */ public JavaStackSetWrapper(LinkedHashSet linkedHashSet) { this.linkedHashSet = linkedHashSet; } diff --git a/src/main/java/org/warp/commonutils/type/StackSet.java b/src/main/java/org/warp/commonutils/type/StackSet.java index 64a8009..51ea09d 100644 --- a/src/main/java/org/warp/commonutils/type/StackSet.java +++ b/src/main/java/org/warp/commonutils/type/StackSet.java @@ -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 * *

A stack must provide the classical {@link #push(Object)} and - * {@link #pop()} operations, but may be also peekable - * 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 peekable 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 { - /** 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). * *

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() { + default K top() { return peek(0); } - /** Peeks at an element on the stack (optional operation). + /** + * Peeks at an element on the stack (optional operation). * *

This default implementation just throws an {@link UnsupportedOperationException}. * @@ -61,7 +63,6 @@ public interface StackSet { * @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(); } diff --git a/src/test/java/org/warp/commonutils/type/TestStackSet.java b/src/test/java/org/warp/commonutils/type/TestStackSet.java index af183a1..496ead4 100644 --- a/src/test/java/org/warp/commonutils/type/TestStackSet.java +++ b/src/test/java/org/warp/commonutils/type/TestStackSet.java @@ -117,6 +117,22 @@ public class TestStackSet { } } + @Test + public void testStackSetCopyOrder() { + for (StackSet implementation : getImplementations()) { + implementation.push("testBottom"); + implementation.push("testMiddle"); + implementation.push("testTop"); + if (implementation instanceof FastUtilStackSetWrapper) { + var copy = new HashStackSet<>((FastUtilStackSetWrapper) 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 implementation : getImplementations()) {