From 9f179ab32c4512ad1ad3726a533179e0453c73f0 Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Mon, 14 Dec 2020 03:12:51 +0100 Subject: [PATCH] Add ArrayStack --- .../org/warp/commonutils/type/ArrayStack.java | 15 +++ .../type/FastUtilStackSetWrapper.java | 10 +- .../type/FastUtilStackWrapper.java | 123 ++++++++++++++++++ .../warp/commonutils/type/HashStackSet.java | 9 ++ .../java/org/warp/commonutils/type/Stack.java | 43 ++++++ .../org/warp/commonutils/type/StackSet.java | 22 +++- 6 files changed, 217 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/warp/commonutils/type/ArrayStack.java create mode 100644 src/main/java/org/warp/commonutils/type/FastUtilStackWrapper.java create mode 100644 src/main/java/org/warp/commonutils/type/Stack.java diff --git a/src/main/java/org/warp/commonutils/type/ArrayStack.java b/src/main/java/org/warp/commonutils/type/ArrayStack.java new file mode 100644 index 0000000..3345c98 --- /dev/null +++ b/src/main/java/org/warp/commonutils/type/ArrayStack.java @@ -0,0 +1,15 @@ +package org.warp.commonutils.type; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import java.util.Collection; + +public class ArrayStack extends FastUtilStackWrapper { + + public ArrayStack() { + super(new ObjectArrayList()); + } + + public ArrayStack(Collection stack) { + super(new ObjectArrayList(stack)); + } +} diff --git a/src/main/java/org/warp/commonutils/type/FastUtilStackSetWrapper.java b/src/main/java/org/warp/commonutils/type/FastUtilStackSetWrapper.java index 9c1ba32..5c5d857 100644 --- a/src/main/java/org/warp/commonutils/type/FastUtilStackSetWrapper.java +++ b/src/main/java/org/warp/commonutils/type/FastUtilStackSetWrapper.java @@ -7,8 +7,8 @@ import org.warp.commonutils.error.IndexOutOfBoundsException; public class FastUtilStackSetWrapper implements StackSet, Collection { - private final AddStrategy addStrategy; - private final ObjectLinkedOpenHashSet linkedHashSet; + protected final AddStrategy addStrategy; + protected final ObjectLinkedOpenHashSet linkedHashSet; /** * The first element will be the head @@ -133,4 +133,10 @@ public class FastUtilStackSetWrapper implements StackSet, Collection { } return it.next(); } + + @SuppressWarnings("MethodDoesntCallSuperMethod") + @Override + public FastUtilStackSetWrapper clone() { + return new FastUtilStackSetWrapper<>(linkedHashSet.clone(), addStrategy); + } } diff --git a/src/main/java/org/warp/commonutils/type/FastUtilStackWrapper.java b/src/main/java/org/warp/commonutils/type/FastUtilStackWrapper.java new file mode 100644 index 0000000..ac39fd2 --- /dev/null +++ b/src/main/java/org/warp/commonutils/type/FastUtilStackWrapper.java @@ -0,0 +1,123 @@ +package org.warp.commonutils.type; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Objects; +import java.util.StringJoiner; +import org.jetbrains.annotations.NotNull; + +public class FastUtilStackWrapper implements Stack, Collection { + + private final it.unimi.dsi.fastutil.Stack stack; + private final Collection collection; + + public & Collection> FastUtilStackWrapper(U stack) { + this.stack = stack; + this.collection = stack; + } + + @Override + public void push(T o) { + this.stack.push(o); + } + + @Override + public T pop() { + return this.stack.pop(); + } + + @Override + public int size() { + return collection.size(); + } + + @Override + public boolean isEmpty() { + return this.stack.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return collection.contains(o); + } + + @NotNull + @Override + public Iterator iterator() { + return collection.iterator(); + } + + @NotNull + @Override + public Object[] toArray() { + return collection.toArray(); + } + + @NotNull + @Override + public T1[] toArray(@NotNull T1[] a) { + //noinspection SuspiciousToArrayCall + return collection.toArray(a); + } + + @Override + public boolean add(T t) { + return collection.add(t); + } + + @Override + public boolean remove(Object o) { + return collection.remove(o); + } + + @Override + public boolean containsAll(@NotNull Collection c) { + return collection.containsAll(c); + } + + @Override + public boolean addAll(@NotNull Collection c) { + return collection.addAll(c); + } + + @Override + public boolean removeAll(@NotNull Collection c) { + return collection.removeAll(c); + } + + @Override + public boolean retainAll(@NotNull Collection c) { + return collection.retainAll(c); + } + + @Override + public void clear() { + collection.clear(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + FastUtilStackWrapper that = (FastUtilStackWrapper) o; + + return Objects.equals(stack, that.stack); + } + + @Override + public int hashCode() { + return stack != null ? stack.hashCode() : 0; + } + + @Override + public String toString() { + return new StringJoiner(", ", FastUtilStackWrapper.class.getSimpleName() + "[", "]") + .add("stack=" + stack) + .toString(); + } +} diff --git a/src/main/java/org/warp/commonutils/type/HashStackSet.java b/src/main/java/org/warp/commonutils/type/HashStackSet.java index 8472fee..973373c 100644 --- a/src/main/java/org/warp/commonutils/type/HashStackSet.java +++ b/src/main/java/org/warp/commonutils/type/HashStackSet.java @@ -16,4 +16,13 @@ public class HashStackSet extends FastUtilStackSetWrapper { public HashStackSet(AddStrategy addStrategy) { super(new ObjectLinkedOpenHashSet<>(), addStrategy); } + + private HashStackSet(ObjectLinkedOpenHashSet linkedHashSet, AddStrategy addStrategy) { + super(linkedHashSet, addStrategy); + } + + @Override + public HashStackSet clone() { + return new HashStackSet<>(super.linkedHashSet.clone(), super.addStrategy); + } } diff --git a/src/main/java/org/warp/commonutils/type/Stack.java b/src/main/java/org/warp/commonutils/type/Stack.java new file mode 100644 index 0000000..9dc3dac --- /dev/null +++ b/src/main/java/org/warp/commonutils/type/Stack.java @@ -0,0 +1,43 @@ +package org.warp.commonutils.type; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.warp.commonutils.error.IndexOutOfBoundsException; + +/** + * A stack + * + *

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). + */ + +public interface Stack extends it.unimi.dsi.fastutil.Stack { + + /** + * Pop multiple times + * @param count the number of times to pop + * @return list of popped elements + */ + default List pop(int count) { + if (count < 0) { + throw new IndexOutOfBoundsException(count); + } + var items = new ArrayList(count); + for (int i = 0; i < count; i++) { + items.add(this.pop()); + } + return items; + } + + static Stack create() { + return new ArrayStack<>(); + } + + static & Collection> Stack wrap(U stack) { + return new FastUtilStackWrapper<>(stack); + } + +} diff --git a/src/main/java/org/warp/commonutils/type/StackSet.java b/src/main/java/org/warp/commonutils/type/StackSet.java index 51ea09d..cba719d 100644 --- a/src/main/java/org/warp/commonutils/type/StackSet.java +++ b/src/main/java/org/warp/commonutils/type/StackSet.java @@ -1,11 +1,11 @@ package org.warp.commonutils.type; import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; -import java.util.Iterator; +import java.util.ArrayList; import java.util.LinkedHashSet; +import java.util.List; import java.util.NoSuchElementException; -import java.util.Objects; -import java.util.function.Predicate; +import org.warp.commonutils.error.IndexOutOfBoundsException; /** * A stack but with the behavior of a Linked HashSet @@ -27,6 +27,22 @@ public interface StackSet { */ boolean push(K o); + /** + * Pop multiple times + * @param count the number of times to pop + * @return list of popped elements + */ + default List pop(int count) { + if (count < 0) { + throw new IndexOutOfBoundsException(count); + } + var items = new ArrayList(count); + for (int i = 0; i < count; i++) { + items.add(this.pop()); + } + return items; + } + /** * Pops the top off the stack. *