-
+
- com.google.guava
- guava
+ net.automatalib
+ automata-commons-util
diff --git a/commons/smartcollections/src/main/java/module-info.java b/commons/smartcollections/src/main/java/module-info.java
index da430ef43a..ce5f04ef25 100644
--- a/commons/smartcollections/src/main/java/module-info.java
+++ b/commons/smartcollections/src/main/java/module-info.java
@@ -30,7 +30,7 @@
*/
open module net.automatalib.common.smartcollection {
- requires com.google.common;
+ requires net.automatalib.common.util;
requires org.checkerframework.checker.qual;
exports net.automatalib.common.smartcollection;
diff --git a/commons/util/src/main/java/net/automatalib/common/util/array/AWUtil.java b/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/AWUtil.java
similarity index 97%
rename from commons/util/src/main/java/net/automatalib/common/util/array/AWUtil.java
rename to commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/AWUtil.java
index 9335521b4e..82aeed5938 100644
--- a/commons/util/src/main/java/net/automatalib/common/util/array/AWUtil.java
+++ b/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/AWUtil.java
@@ -13,12 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.automatalib.common.util.array;
+package net.automatalib.common.smartcollection;
import java.util.Arrays;
-import net.automatalib.common.smartcollection.ArrayWritable;
-
/**
* Utility class for writing containers to arrays.
*
diff --git a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/AbstractSmartCollection.java b/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/AbstractSmartCollection.java
index a891dc5875..43f571eb34 100644
--- a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/AbstractSmartCollection.java
+++ b/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/AbstractSmartCollection.java
@@ -20,7 +20,7 @@
import java.util.Iterator;
import java.util.Objects;
-import com.google.common.collect.Iterators;
+import net.automatalib.common.util.collection.IteratorUtil;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
@@ -90,7 +90,7 @@ public void deepClear() {
@Override
public Iterator iterator() {
- return Iterators.transform(referenceIterator(), this::get);
+ return IteratorUtil.map(referenceIterator(), this::get);
}
@Override
diff --git a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/BackedGeneralPriorityQueue.java b/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/BackedGeneralPriorityQueue.java
index eb42a6abe9..507a579e68 100644
--- a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/BackedGeneralPriorityQueue.java
+++ b/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/BackedGeneralPriorityQueue.java
@@ -21,7 +21,7 @@
import java.util.Objects;
import java.util.function.Supplier;
-import com.google.common.collect.Iterators;
+import net.automatalib.common.util.collection.IteratorUtil;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
@@ -116,7 +116,7 @@ public void deepClear() {
@SuppressWarnings("nullness") // function is only called on elements of the iterator for which we know non-nullness
@Override
public Iterator iterator() {
- return Iterators.transform(backingQueue.iterator(), e -> e.element);
+ return IteratorUtil.map(backingQueue.iterator(), e -> e.element);
}
@Override
diff --git a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/BinaryHeap.java b/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/BinaryHeap.java
index ff1c31c630..376523f115 100644
--- a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/BinaryHeap.java
+++ b/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/BinaryHeap.java
@@ -22,6 +22,7 @@
import java.util.PriorityQueue;
import java.util.Queue;
+import net.automatalib.common.util.array.ResizingArrayStorage;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import org.checkerframework.checker.nullness.qual.Nullable;
diff --git a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/UnorderedCollection.java b/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/UnorderedCollection.java
index f5b32fb83a..42b3e08f54 100644
--- a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/UnorderedCollection.java
+++ b/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/UnorderedCollection.java
@@ -19,6 +19,7 @@
import java.util.Iterator;
import java.util.NoSuchElementException;
+import net.automatalib.common.util.array.ResizingArrayStorage;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
/**
diff --git a/commons/smartcollections/src/test/java/net/automatalib/common/smartcollection/BackedGeneralPriorityQueueTest.java b/commons/smartcollections/src/test/java/net/automatalib/common/smartcollection/BackedGeneralPriorityQueueTest.java
index 58de07143a..1ec4cf8587 100644
--- a/commons/smartcollections/src/test/java/net/automatalib/common/smartcollection/BackedGeneralPriorityQueueTest.java
+++ b/commons/smartcollections/src/test/java/net/automatalib/common/smartcollection/BackedGeneralPriorityQueueTest.java
@@ -15,12 +15,12 @@
*/
package net.automatalib.common.smartcollection;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
-import com.google.common.collect.Lists;
-import com.google.common.primitives.Ints;
+import net.automatalib.common.util.collection.CollectionUtil;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -31,8 +31,8 @@ public class BackedGeneralPriorityQueueTest {
@BeforeClass
public void setUp() {
- final List values = Lists.charactersOf("abcdefghij");
- final List keys = Ints.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+ final List values = CollectionUtil.charRange('a', 'k');
+ final List keys = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Collections.reverse(keys);
this.queue = new BackedGeneralPriorityQueue<>(values, keys);
diff --git a/commons/smartcollections/src/test/java/net/automatalib/common/smartcollection/IntSeqTest.java b/commons/smartcollections/src/test/java/net/automatalib/common/smartcollection/IntSeqTest.java
index 85ccadbf0c..adebc1d86d 100644
--- a/commons/smartcollections/src/test/java/net/automatalib/common/smartcollection/IntSeqTest.java
+++ b/commons/smartcollections/src/test/java/net/automatalib/common/smartcollection/IntSeqTest.java
@@ -15,7 +15,10 @@
*/
package net.automatalib.common.smartcollection;
-import com.google.common.primitives.Ints;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -24,15 +27,18 @@ public class IntSeqTest {
private final int[] arr1 = {1, 2, 3, 4, 5, 6};
private final int[] arr2 = {31, 43, 45, 1, 3445, 56};
+ private final List asList1 = IntStream.of(arr1).boxed().collect(Collectors.toList());
+ private final List asList2 = IntStream.of(arr2).boxed().collect(Collectors.toList());
+
@Test
public void testArrays() {
- Assert.assertEquals(IntSeq.of(arr1), Ints.asList(arr1));
- Assert.assertEquals(IntSeq.of(arr2), Ints.asList(arr2));
+ Assert.assertEquals(IntSeq.of(arr1), asList1);
+ Assert.assertEquals(IntSeq.of(arr2), asList2);
}
@Test
public void testLists() {
- Assert.assertEquals(IntSeq.of(Ints.asList(arr1)), Ints.asList(arr1));
- Assert.assertEquals(IntSeq.of(Ints.asList(arr2)), Ints.asList(arr2));
+ Assert.assertEquals(IntSeq.of(asList1), asList1);
+ Assert.assertEquals(IntSeq.of(asList2), asList2);
}
}
diff --git a/commons/smartcollections/src/test/java/net/automatalib/common/smartcollection/ReflexiveMapViewTest.java b/commons/smartcollections/src/test/java/net/automatalib/common/smartcollection/ReflexiveMapViewTest.java
index b77b332f03..5d792bda50 100644
--- a/commons/smartcollections/src/test/java/net/automatalib/common/smartcollection/ReflexiveMapViewTest.java
+++ b/commons/smartcollections/src/test/java/net/automatalib/common/smartcollection/ReflexiveMapViewTest.java
@@ -15,18 +15,18 @@
*/
package net.automatalib.common.smartcollection;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import com.google.common.collect.Sets;
import org.testng.Assert;
import org.testng.annotations.Test;
public class ReflexiveMapViewTest {
- private final Set elements = Sets.newHashSet(1, 2, 3, 4, 5);
+ private final Set elements = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
private final Map map = new ReflexiveMapView<>(elements);
@Test
diff --git a/commons/util/pom.xml b/commons/util/pom.xml
index 0ee206a5c0..053594c4e0 100644
--- a/commons/util/pom.xml
+++ b/commons/util/pom.xml
@@ -34,17 +34,7 @@ limitations under the License.
-
-
- net.automatalib
- automata-commons-smartcollections
-
-
-
- com.google.guava
- guava
-
org.slf4j
slf4j-api
diff --git a/commons/util/src/main/java/module-info.java b/commons/util/src/main/java/module-info.java
index e360a7d27d..79d3fb5847 100644
--- a/commons/util/src/main/java/module-info.java
+++ b/commons/util/src/main/java/module-info.java
@@ -31,9 +31,6 @@
open module net.automatalib.common.util {
requires java.management;
-
- requires com.google.common;
- requires net.automatalib.common.smartcollection;
requires org.checkerframework.checker.qual;
requires org.slf4j;
@@ -42,6 +39,7 @@
exports net.automatalib.common.util.collection;
exports net.automatalib.common.util.comparison;
exports net.automatalib.common.util.concurrent;
+ exports net.automatalib.common.util.exception;
exports net.automatalib.common.util.fixpoint;
exports net.automatalib.common.util.function;
exports net.automatalib.common.util.io;
diff --git a/commons/util/src/main/java/net/automatalib/common/util/HashUtil.java b/commons/util/src/main/java/net/automatalib/common/util/HashUtil.java
new file mode 100644
index 0000000000..37dcc7a8fd
--- /dev/null
+++ b/commons/util/src/main/java/net/automatalib/common/util/HashUtil.java
@@ -0,0 +1,58 @@
+/* Copyright (C) 2013-2024 TU Dortmund University
+ * This file is part of AutomataLib, http://www.automatalib.net/.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.automatalib.common.util;
+
+/**
+ * Utility class for hash-based datastructures.
+ */
+public final class HashUtil {
+
+ private static final double DEFAULT_LOADFACTOR = 0.75f;
+
+ private HashUtil() {
+ // prevent instantiation
+ }
+
+ /**
+ * Computes the capacity of a hash structure for given number of expected elements. This methods calls
+ * {@link #capacity(int, double)} using {@code 0.75f} as default load factor.
+ *
+ * @param expectedSize
+ * the number of expected elements
+ *
+ * @return the required capacity of the data structure.
+ */
+ public static int capacity(int expectedSize) {
+ return capacity(expectedSize, DEFAULT_LOADFACTOR);
+ }
+
+ /**
+ * Computes the capacity of a hash structure for given number of expected elements. This methods essentially
+ * backports the calculateHashMapCapacity(int)
+ * call from newer JDKs.
+ *
+ * @param expectedSize
+ * the number of expected elements
+ * @param loadFactor
+ * the load factor of the hash structure
+ *
+ * @return the required capacity of the data structure.
+ */
+ public static int capacity(int expectedSize, double loadFactor) {
+ return (int) Math.ceil(expectedSize / loadFactor);
+ }
+}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/IOUtil.java b/commons/util/src/main/java/net/automatalib/common/util/IOUtil.java
index 4d7808abd9..36b7877254 100644
--- a/commons/util/src/main/java/net/automatalib/common/util/IOUtil.java
+++ b/commons/util/src/main/java/net/automatalib/common/util/IOUtil.java
@@ -26,12 +26,12 @@
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
+import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.zip.GZIPInputStream;
-import com.google.common.base.Preconditions;
import net.automatalib.common.util.io.NonClosingInputStream;
import net.automatalib.common.util.io.NonClosingOutputStream;
@@ -40,6 +40,8 @@
*/
public final class IOUtil {
+ public static final int DEFAULT_BUFFER_SIZE = 4096;
+
private IOUtil() {
// prevent instantiation
}
@@ -64,7 +66,9 @@ private IOUtil() {
* if the stream does not support {@link InputStream#markSupported() marking}
*/
public static InputStream asUncompressedInputStream(InputStream is) throws IOException {
- Preconditions.checkArgument(is.markSupported(), "input stream must support marking");
+ if (!is.markSupported()) {
+ throw new IllegalArgumentException("input stream must support marking");
+ }
is.mark(2);
byte[] buf = new byte[2];
@@ -334,4 +338,40 @@ private static boolean isBufferedInputStream(InputStream is) {
private static boolean isBufferedOutputStream(OutputStream os) {
return os instanceof BufferedOutputStream || os instanceof ByteArrayOutputStream;
}
+
+ /**
+ * Copies the contents of the given reader into the given writer.
+ *
+ * @param in
+ * the reader to read data from
+ * @param out
+ * the writer to write data to
+ *
+ * @throws IOException
+ * if reading from or writing to the respective reader / writer throws this exception
+ */
+ public static void copy(Reader in, Writer out) throws IOException {
+ final char[] buf = new char[DEFAULT_BUFFER_SIZE];
+ int read;
+ while ((read = in.read(buf)) >= 0) {
+ out.write(buf, 0, read);
+ }
+ }
+
+ /**
+ * Reads the data from the given reader and returns its contents as a string.
+ *
+ * @param r
+ * the reader to read data from
+ *
+ * @return the contents of the reader as a string
+ *
+ * @throws IOException
+ * if reading from the reader throws this exception
+ */
+ public static String toString(Reader r) throws IOException {
+ final StringWriter w = new StringWriter();
+ copy(r, w);
+ return w.toString();
+ }
}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/ReflectUtil.java b/commons/util/src/main/java/net/automatalib/common/util/ReflectUtil.java
index 64c0f9192e..5737986f31 100644
--- a/commons/util/src/main/java/net/automatalib/common/util/ReflectUtil.java
+++ b/commons/util/src/main/java/net/automatalib/common/util/ReflectUtil.java
@@ -17,8 +17,10 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
-import com.google.common.primitives.Primitives;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
@@ -26,6 +28,21 @@
*/
public final class ReflectUtil {
+ private static final Map, Class>> CLASS_TO_PRIMITIVE;
+
+ static {
+ CLASS_TO_PRIMITIVE = new HashMap<>();
+ CLASS_TO_PRIMITIVE.put(Boolean.class, boolean.class);
+ CLASS_TO_PRIMITIVE.put(Byte.class, byte.class);
+ CLASS_TO_PRIMITIVE.put(Character.class, char.class);
+ CLASS_TO_PRIMITIVE.put(Double.class, double.class);
+ CLASS_TO_PRIMITIVE.put(Float.class, float.class);
+ CLASS_TO_PRIMITIVE.put(Integer.class, int.class);
+ CLASS_TO_PRIMITIVE.put(Long.class, long.class);
+ CLASS_TO_PRIMITIVE.put(Short.class, short.class);
+ CLASS_TO_PRIMITIVE.put(Void.class, void.class);
+ }
+
private ReflectUtil() {}
/**
@@ -177,9 +194,9 @@ private static boolean w2pEquals(Class>[] a, Class>... b) {
}
private static boolean w2pEquals(Class> a, Class> b) {
- final Class> wrappedA = Primitives.unwrap(a);
- final Class> wrappedB = Primitives.unwrap(b);
- return wrappedA.equals(wrappedB);
+ final Class> primA = CLASS_TO_PRIMITIVE.getOrDefault(a, a);
+ final Class> primB = CLASS_TO_PRIMITIVE.getOrDefault(b, b);
+ return Objects.equals(primA, primB);
}
private static boolean isMatch(Class>[] paramTypes, @Nullable Object... args) {
@@ -195,7 +212,7 @@ private static boolean isMatch(Class>[] paramTypes, @Nullable Object... args)
return false;
}
Class> argType = arg.getClass();
- if (paramType != Primitives.unwrap(argType)) {
+ if (paramType != CLASS_TO_PRIMITIVE.get(argType)) {
return false;
}
} else {
diff --git a/commons/util/src/main/java/net/automatalib/common/util/array/ArrayIterator.java b/commons/util/src/main/java/net/automatalib/common/util/array/ArrayIterator.java
new file mode 100644
index 0000000000..da905c296e
--- /dev/null
+++ b/commons/util/src/main/java/net/automatalib/common/util/array/ArrayIterator.java
@@ -0,0 +1,44 @@
+/* Copyright (C) 2013-2024 TU Dortmund University
+ * This file is part of AutomataLib, http://www.automatalib.net/.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.automatalib.common.util.array;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+class ArrayIterator implements Iterator {
+
+ private final T[] delegate;
+ private int idx;
+
+ ArrayIterator(T[] delegate) {
+ this.delegate = delegate;
+ this.idx = 0;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return idx < delegate.length;
+ }
+
+ @Override
+ public T next() {
+ if (hasNext()) {
+ return delegate[idx++];
+ }
+
+ throw new NoSuchElementException();
+ }
+}
diff --git a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/ArrayStorage.java b/commons/util/src/main/java/net/automatalib/common/util/array/ArrayStorage.java
similarity index 98%
rename from commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/ArrayStorage.java
rename to commons/util/src/main/java/net/automatalib/common/util/array/ArrayStorage.java
index 5cda96036e..4c1e2717e6 100644
--- a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/ArrayStorage.java
+++ b/commons/util/src/main/java/net/automatalib/common/util/array/ArrayStorage.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.automatalib.common.smartcollection;
+package net.automatalib.common.util.array;
import java.util.AbstractList;
import java.util.Arrays;
diff --git a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/ArrayUtil.java b/commons/util/src/main/java/net/automatalib/common/util/array/ArrayUtil.java
similarity index 84%
rename from commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/ArrayUtil.java
rename to commons/util/src/main/java/net/automatalib/common/util/array/ArrayUtil.java
index 7e71bd3e68..dc66721379 100644
--- a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/ArrayUtil.java
+++ b/commons/util/src/main/java/net/automatalib/common/util/array/ArrayUtil.java
@@ -13,7 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.automatalib.common.smartcollection;
+package net.automatalib.common.util.array;
+
+import java.util.Iterator;
/**
* Utility methods for arrays.
@@ -73,4 +75,18 @@ public static int computeNewCapacity(int length, int requiredCapacity, int nextC
return newCapacity;
}
+
+ /**
+ * Returns an immutable iterator that iterates over the contents of the given array.
+ *
+ * @param array
+ * the array over whose contents should be iterated
+ * @param
+ * element type
+ *
+ * @return an iterator for the contents of the array
+ */
+ public static Iterator iterator(E[] array) {
+ return new ArrayIterator<>(array);
+ }
}
diff --git a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/ResizingArrayStorage.java b/commons/util/src/main/java/net/automatalib/common/util/array/ResizingArrayStorage.java
similarity index 93%
rename from commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/ResizingArrayStorage.java
rename to commons/util/src/main/java/net/automatalib/common/util/array/ResizingArrayStorage.java
index f19803b5d9..9aaf0d6fcc 100644
--- a/commons/smartcollections/src/main/java/net/automatalib/common/smartcollection/ResizingArrayStorage.java
+++ b/commons/util/src/main/java/net/automatalib/common/util/array/ResizingArrayStorage.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package net.automatalib.common.smartcollection;
+package net.automatalib.common.util.array;
import java.lang.reflect.Array;
import java.util.Arrays;
@@ -24,7 +24,7 @@
* @param
* element class.
*/
-public final class ResizingArrayStorage implements CapacityManagement {
+public final class ResizingArrayStorage {
/**
* The default initial capacity of the array storage.
@@ -69,7 +69,6 @@ public ResizingArrayStorage(ResizingArrayStorage other) {
this.nextCapacityHint = other.nextCapacityHint;
}
- @Override
public boolean ensureCapacity(int minCapacity) {
if (minCapacity <= array.length) {
return false;
@@ -82,12 +81,6 @@ public boolean ensureCapacity(int minCapacity) {
return true;
}
- @Override
- public boolean ensureAdditionalCapacity(int additionalCapacity) {
- return ensureCapacity(array.length + additionalCapacity);
- }
-
- @Override
public void hintNextCapacity(int nextCapacityHint) {
this.nextCapacityHint = nextCapacityHint;
}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/AbstractSimplifiedIterator.java b/commons/util/src/main/java/net/automatalib/common/util/collection/AbstractSimplifiedIterator.java
new file mode 100644
index 0000000000..07a85579a9
--- /dev/null
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/AbstractSimplifiedIterator.java
@@ -0,0 +1,77 @@
+/* Copyright (C) 2013-2024 TU Dortmund University
+ * This file is part of AutomataLib, http://www.automatalib.net/.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.automatalib.common.util.collection;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * A simplified immutable iterator that only requires to implement the calculation of the next element.
+ *
+ * @param
+ * element type
+ */
+public abstract class AbstractSimplifiedIterator implements Iterator {
+
+ protected E nextValue;
+ private State state = State.AWAIT_NEXT;
+
+ private enum State {
+ AWAIT_NEXT,
+ HAS_NEXT,
+ FINISHED
+ }
+
+ /**
+ * The method to calculate the next element. This method must set the {@link #nextValue} reference to
+ * indicate the next object and return {@code true} to signal that the next element is valid.
+ *
+ * @return {@code true} if the next element is valid, {@code false} if no more elements can be computed
+ */
+ protected abstract boolean calculateNext();
+
+ private boolean advance() {
+ boolean ret = calculateNext();
+ if (!ret) {
+ state = State.FINISHED;
+ } else {
+ state = State.HAS_NEXT;
+ }
+ return ret;
+ }
+
+ @Override
+ public boolean hasNext() {
+ switch (state) {
+ case AWAIT_NEXT:
+ return advance();
+ case HAS_NEXT:
+ return true;
+ default: // case FINISHED:
+ return false;
+ }
+ }
+
+ @Override
+ public E next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ state = State.AWAIT_NEXT;
+ return nextValue;
+ }
+
+}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/BatchingIterator.java b/commons/util/src/main/java/net/automatalib/common/util/collection/BatchingIterator.java
new file mode 100644
index 0000000000..e264fa4dd4
--- /dev/null
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/BatchingIterator.java
@@ -0,0 +1,54 @@
+/* Copyright (C) 2013-2024 TU Dortmund University
+ * This file is part of AutomataLib, http://www.automatalib.net/.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.automatalib.common.util.collection;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+class BatchingIterator implements Iterator> {
+
+ private final int batchSize;
+ private final Iterator source;
+ private final List batch;
+
+ BatchingIterator(Iterator source, int batchSize) {
+ this.batchSize = batchSize;
+ this.source = source;
+ this.batch = new ArrayList<>(batchSize);
+ }
+
+ @Override
+ public boolean hasNext() {
+ return source.hasNext();
+ }
+
+ @Override
+ public List next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ this.batch.clear();
+
+ while (batch.size() < batchSize && source.hasNext()) {
+ batch.add(source.next());
+ }
+
+ return batch;
+ }
+}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/CharRange.java b/commons/util/src/main/java/net/automatalib/common/util/collection/CharRange.java
index 9d6a4822f1..41ba208d2f 100644
--- a/commons/util/src/main/java/net/automatalib/common/util/collection/CharRange.java
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/CharRange.java
@@ -18,10 +18,9 @@
import java.util.AbstractList;
import java.util.RandomAccess;
-import net.automatalib.common.smartcollection.ArrayWritable;
import org.checkerframework.checker.nullness.qual.Nullable;
-public class CharRange extends AbstractList implements ArrayWritable, RandomAccess {
+public class CharRange extends AbstractList implements RandomAccess {
private final IntRange delegate;
@@ -87,13 +86,4 @@ public CharRangeIterator listIterator(int index) {
public int size() {
return delegate.size();
}
-
- @Override
- public void writeToArray(int offset, @Nullable Object[] array, int tgtOfs, int num) {
- int si = offset;
- int ti = tgtOfs;
- for (int i = 0; i < num; i++) {
- array[ti++] = charGet(si++);
- }
- }
}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/CharStringRange.java b/commons/util/src/main/java/net/automatalib/common/util/collection/CharStringRange.java
index 97d3bce52f..37e0369deb 100644
--- a/commons/util/src/main/java/net/automatalib/common/util/collection/CharStringRange.java
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/CharStringRange.java
@@ -18,10 +18,9 @@
import java.util.AbstractList;
import java.util.RandomAccess;
-import net.automatalib.common.smartcollection.ArrayWritable;
import org.checkerframework.checker.nullness.qual.Nullable;
-public class CharStringRange extends AbstractList implements ArrayWritable, RandomAccess {
+public class CharStringRange extends AbstractList implements RandomAccess {
private final IntRange delegate;
@@ -90,13 +89,4 @@ public CharStringRangeIterator listIterator(int index) {
public int size() {
return delegate.size();
}
-
- @Override
- public void writeToArray(int offset, @Nullable Object[] array, int tgtOfs, int num) {
- int si = offset;
- int ti = tgtOfs;
- for (int i = 0; i < num; i++) {
- array[ti++] = get(si++);
- }
- }
}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/CollectionUtil.java b/commons/util/src/main/java/net/automatalib/common/util/collection/CollectionUtil.java
new file mode 100644
index 0000000000..de4179aacf
--- /dev/null
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/CollectionUtil.java
@@ -0,0 +1,115 @@
+/* Copyright (C) 2013-2024 TU Dortmund University
+ * This file is part of AutomataLib, http://www.automatalib.net/.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.automatalib.common.util.collection;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.RandomAccess;
+import java.util.function.Function;
+
+/**
+ * Various methods for operating on {@link Collection}s.
+ */
+public final class CollectionUtil {
+
+ private CollectionUtil() {
+ // prevent instantiation.
+ }
+
+ public static List intRange(int start, int end) {
+ return new IntRange(start, end);
+ }
+
+ public static List intRange(int start, int end, int step) {
+ return new IntRange(start, end, step);
+ }
+
+ public static List charRange(char start, char end) {
+ return new CharRange(start, end);
+ }
+
+ public static List charStringRange(char start, char end) {
+ return new CharStringRange(start, end);
+ }
+
+ public static List extends T> randomAccessList(Collection extends T> coll) {
+ if (coll instanceof List && coll instanceof RandomAccess) {
+ return (List extends T>) coll;
+ }
+ return new ArrayList<>(coll);
+ }
+
+ /**
+ * Returns a (mutable) view on the given collection that transforms its elements as specified by the given mapping.
+ *
+ * @param collection
+ * the source collection
+ * @param mapping
+ * the transformation function
+ * @param
+ * mapping domain type
+ * @param
+ * mapping range type
+ *
+ * @return the mapped view on the given collection
+ */
+ public static Collection map(Collection collection, Function super D, ? extends R> mapping) {
+ return new MappingCollection<>(collection, mapping);
+ }
+
+ /**
+ * Constructs a list from the given elements.
+ *
+ * @param first
+ * the first (mandatory) element
+ * @param rest
+ * the remaining (optional) elements
+ * @param
+ * element type
+ *
+ * @return a list containing the specified elements
+ */
+ @SafeVarargs
+ public static List list(T first, T... rest) {
+ final List result = new ArrayList<>(rest.length + 1);
+ result.add(first);
+ Collections.addAll(result, rest);
+ return result;
+ }
+
+ /**
+ * Adds all elements of the given iterator to the given collection.
+ *
+ * @param collection
+ * the collection to add elements to
+ * @param iterator
+ * the iterator to provide the elements to add
+ * @param
+ * element type
+ *
+ * @return {@code true} of the collection has {@link Collection#add(Object) changed}, {@code false} otherwise.
+ */
+ public static boolean add(Collection collection, Iterator iterator) {
+ boolean changed = false;
+ while (iterator.hasNext()) {
+ changed |= collection.add(iterator.next());
+ }
+ return changed;
+ }
+}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/ConcatIterable.java b/commons/util/src/main/java/net/automatalib/common/util/collection/ConcatIterable.java
new file mode 100644
index 0000000000..ec914232ba
--- /dev/null
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/ConcatIterable.java
@@ -0,0 +1,40 @@
+/* Copyright (C) 2013-2024 TU Dortmund University
+ * This file is part of AutomataLib, http://www.automatalib.net/.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.automatalib.common.util.collection;
+
+import java.util.Iterator;
+
+import net.automatalib.common.util.array.ArrayUtil;
+
+class ConcatIterable extends AbstractTwoLevelIterator, T, T> {
+
+ @SafeVarargs
+ ConcatIterable(Iterable extends T>... delegates) {
+ super(ArrayUtil.iterator(delegates));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Iterator l2Iterator(Iterable extends T> l1Object) {
+ return (Iterator) l1Object.iterator();
+ }
+
+ @Override
+ protected T combine(Iterable extends T> l1Object, T l2Object) {
+ return l2Object;
+ }
+
+}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/ConcatIterator.java b/commons/util/src/main/java/net/automatalib/common/util/collection/ConcatIterator.java
new file mode 100644
index 0000000000..28e15ae38a
--- /dev/null
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/ConcatIterator.java
@@ -0,0 +1,40 @@
+/* Copyright (C) 2013-2024 TU Dortmund University
+ * This file is part of AutomataLib, http://www.automatalib.net/.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.automatalib.common.util.collection;
+
+import java.util.Iterator;
+
+import net.automatalib.common.util.array.ArrayUtil;
+
+class ConcatIterator extends AbstractTwoLevelIterator, T, T> {
+
+ @SafeVarargs
+ ConcatIterator(Iterator extends T>... delegates) {
+ super(ArrayUtil.iterator(delegates));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Iterator l2Iterator(Iterator extends T> l1Object) {
+ return (Iterator) l1Object;
+ }
+
+ @Override
+ protected T combine(Iterator extends T> l1Object, T l2Object) {
+ return l2Object;
+ }
+
+}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/FilteringIterator.java b/commons/util/src/main/java/net/automatalib/common/util/collection/FilteringIterator.java
new file mode 100644
index 0000000000..ea4626ab92
--- /dev/null
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/FilteringIterator.java
@@ -0,0 +1,42 @@
+/* Copyright (C) 2013-2024 TU Dortmund University
+ * This file is part of AutomataLib, http://www.automatalib.net/.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.automatalib.common.util.collection;
+
+import java.util.Iterator;
+import java.util.function.Predicate;
+
+class FilteringIterator extends AbstractSimplifiedIterator {
+
+ private final Iterator delegate;
+ private final Predicate super T> predicate;
+
+ FilteringIterator(Iterator delegate, Predicate super T> predicate) {
+ this.delegate = delegate;
+ this.predicate = predicate;
+ }
+
+ @Override
+ protected boolean calculateNext() {
+ while (delegate.hasNext()) {
+ final T n = delegate.next();
+ if (predicate.test(n)) {
+ super.nextValue = n;
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/IntRange.java b/commons/util/src/main/java/net/automatalib/common/util/collection/IntRange.java
index c63d6f706e..4474d8035b 100644
--- a/commons/util/src/main/java/net/automatalib/common/util/collection/IntRange.java
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/IntRange.java
@@ -18,10 +18,9 @@
import java.util.AbstractList;
import java.util.RandomAccess;
-import net.automatalib.common.smartcollection.ArrayWritable;
import org.checkerframework.checker.nullness.qual.Nullable;
-public final class IntRange extends AbstractList implements ArrayWritable, RandomAccess {
+public final class IntRange extends AbstractList implements RandomAccess {
private final int start;
private final int step;
@@ -103,15 +102,4 @@ public IntRangeIterator listIterator(int index) {
public int size() {
return size;
}
-
- @Override
- public void writeToArray(int offset, @Nullable Object[] array, int tgtOfs, int num) {
- int x = start + offset * step;
- int ti = tgtOfs;
- for (int i = 0; i < num; i++) {
- array[ti++] = x;
- x += step;
- }
- }
-
}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/CollectionsUtil.java b/commons/util/src/main/java/net/automatalib/common/util/collection/IterableUtil.java
similarity index 63%
rename from commons/util/src/main/java/net/automatalib/common/util/collection/CollectionsUtil.java
rename to commons/util/src/main/java/net/automatalib/common/util/collection/IterableUtil.java
index 442ca5d77f..6764a6100c 100644
--- a/commons/util/src/main/java/net/automatalib/common/util/collection/CollectionsUtil.java
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/IterableUtil.java
@@ -15,43 +15,20 @@
*/
package net.automatalib.common.util.collection;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import java.util.RandomAccess;
+import java.util.function.Function;
+import java.util.stream.Stream;
/**
- * Various methods for operating on collections.
+ * Utility methods for {@link Iterable}s.
*/
-public final class CollectionsUtil {
+public final class IterableUtil {
- private CollectionsUtil() {
- // prevent instantiation.
- }
-
- public static List intRange(int start, int end) {
- return new IntRange(start, end);
- }
-
- public static List intRange(int start, int end, int step) {
- return new IntRange(start, end, step);
- }
-
- public static List charRange(char start, char end) {
- return new CharRange(start, end);
- }
-
- public static List charStringRange(char start, char end) {
- return new CharStringRange(start, end);
- }
-
- public static List extends T> randomAccessList(Collection extends T> coll) {
- if (coll instanceof List && coll instanceof RandomAccess) {
- return (List extends T>) coll;
- }
- return new ArrayList<>(coll);
+ private IterableUtil() {
+ // prevent instantiation
}
public static Iterable> allTuples(Iterable extends T> domain, int length) {
@@ -116,4 +93,68 @@ public static Iterable> cartesianProduct(Iterable... iterables) {
return () -> new AllCombinationsIterator<>(iterables);
}
+ /**
+ * Returns an iterable that iterates over all elements of the given source iterables.
+ *
+ * @param iterables
+ * the source iterables
+ * @param
+ * element type
+ *
+ * @return the concatenated iterable
+ */
+ @SafeVarargs
+ public static Iterable concat(Iterable extends T>... iterables) {
+ return () -> new ConcatIterable<>(iterables);
+ }
+
+ /**
+ * Returns a view on the given iterable that transforms its elements as specified by the given mapping.
+ *
+ * @param iterable
+ * the source iterable
+ * @param mapping
+ * the transformation function
+ * @param
+ * mapping domain type
+ * @param
+ * mapping range type
+ *
+ * @return the mapped view on the given iterable
+ */
+ public static Iterable map(Iterable iterable, Function super D, ? extends R> mapping) {
+ return () -> new MappingIterator<>(iterable.iterator(), mapping);
+ }
+
+ /**
+ * Returns the number of elements of the given iterable.
+ *
+ * @param iterable
+ * the iterable whose elements should be counted
+ * @param
+ * element type
+ *
+ * @return the number of elements of the iterable
+ */
+ public static int size(Iterable iterable) {
+ if (iterable instanceof Collection) {
+ return ((Collection>) iterable).size();
+ }
+
+ return IteratorUtil.size(iterable.iterator());
+ }
+
+ /**
+ * Transforms the given iterable into a stream.
+ *
+ * @param iterable
+ * the source iterable
+ * @param
+ * element type
+ *
+ * @return the stream-based view on the iterable
+ */
+ public static Stream stream(Iterable iterable) {
+ return IteratorUtil.stream(iterable.iterator());
+ }
}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/IteratorUtil.java b/commons/util/src/main/java/net/automatalib/common/util/collection/IteratorUtil.java
new file mode 100644
index 0000000000..95bd344381
--- /dev/null
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/IteratorUtil.java
@@ -0,0 +1,273 @@
+/* Copyright (C) 2013-2024 TU Dortmund University
+ * This file is part of AutomataLib, http://www.automatalib.net/.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.automatalib.common.util.collection;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.Spliterators;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import net.automatalib.common.util.HashUtil;
+
+/**
+ * Utility methods for {@link Iterator}s.
+ */
+public final class IteratorUtil {
+
+ private IteratorUtil() {
+ // prevent instantiation
+ }
+
+ /**
+ * Checks whether any element provided by the given iterator satisfies the given predicate. Note that the iterator
+ * is consumed in this process.
+ *
+ * @param iterator
+ * the iterator to provide the elements
+ * @param predicate
+ * the predicate to test
+ * @param
+ * element type
+ *
+ * @return {@code true} if at least one element satisfies the predicate, {@code false} otherwise
+ */
+ public static boolean any(Iterator iterator, Predicate super T> predicate) {
+ while (iterator.hasNext()) {
+ if (predicate.test(iterator.next())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns an iterator that aggregates elements of a given source iterator in batches of a given size. While
+ * elements are collected eagerly within a batch, the overall batches are computed lazily. The source iterator is
+ * consumed in this process.
+ *
+ * Note that subsequent calls to the returned iterator's {@link Iterator#next()} method return a reference to the
+ * same batch object, and only update its contents. If you plan to reuse intermediate results, you'll need to
+ * explicitly copy them.
+ *
+ * If the batch size is not a divisor of the number of elements that the iterator provides, the last constructed
+ * batch may not be filled completely.
+ *
+ * @param iterator
+ * the iterator to read the original elements from
+ * @param batchSize
+ * the size of batches that should be constructed
+ * @param
+ * element type
+ *
+ * @return an iterator that provides the original elements in batches of the given size
+ */
+ public static Iterator> batch(Iterator iterator, int batchSize) {
+ return new BatchingIterator<>(iterator, batchSize);
+ }
+
+ /**
+ * Returns an iterator that iterates over all elements of the given source iterators.
+ *
+ * @param iterators
+ * the source iterators
+ * @param
+ * element type
+ *
+ * @return the concatenated iterator
+ */
+ @SafeVarargs
+ public static Iterator concat(Iterator extends T>... iterators) {
+ return new ConcatIterator<>(iterators);
+ }
+
+ /**
+ * A filtered view on the given iterator that only returns elements that satisfy the given predicate.
+ *
+ * @param iterator
+ * the iterator to provide the elements
+ * @param predicate
+ * the size hint for constructing the list
+ * @param
+ * element type
+ *
+ * @return an iterator that only returns elements that satisfy the given predicate
+ */
+ public static Iterator filter(Iterator iterator, Predicate super T> predicate) {
+ return new FilteringIterator<>(iterator, predicate);
+ }
+
+ /**
+ * Collects the elements of the given iterator into a list. Note that the iterator is consumed in this process.
+ *
+ * @param iterator
+ * the iterator to provide the elements
+ * @param
+ * element type
+ *
+ * @return a list containing the elements of the iterator
+ */
+ public static List list(Iterator iterator) {
+ return collection(new ArrayList<>(), iterator);
+ }
+
+ /**
+ * Collects the elements of the given iterator into a list that is initialized with the given size hint. Note that
+ * the iterator is consumed in this process.
+ *
+ * @param iterator
+ * the iterator to provide the elements
+ * @param expectedSize
+ * the size hint for constructing the list
+ * @param
+ * element type
+ *
+ * @return a list containing the elements of the iterator
+ */
+ public static List list(Iterator iterator, int expectedSize) {
+ return collection(new ArrayList<>(expectedSize), iterator);
+ }
+
+ /**
+ * Returns a (mutable) view on the given iterator that transforms its elements as specified by the given mapping.
+ *
+ * @param iterator
+ * the source iterator
+ * @param mapping
+ * the transformation function
+ * @param
+ * mapping domain type
+ * @param
+ * mapping range type
+ *
+ * @return the mapped view on the given iterator
+ */
+ public static Iterator map(Iterator iterator, Function super D, ? extends R> mapping) {
+ return new MappingIterator<>(iterator, mapping);
+ }
+
+ /**
+ * Collects the elements of the given iterator into a set. Note that the iterator is consumed in this process.
+ *
+ * @param iterator
+ * the iterator to provide the elements
+ * @param
+ * element type
+ *
+ * @return a set containing the elements of the iterator
+ */
+ public static Set set(Iterator iterator) {
+ return collection(new HashSet<>(), iterator);
+ }
+
+ /**
+ * Collects the elements of the given iterator into a set that is initialized with the given size hint. Note that
+ * the iterator is consumed in this process.
+ *
+ * @param iterator
+ * the iterator to provide the elements
+ * @param expectedSize
+ * the size hint for constructing the list
+ * @param
+ * element type
+ *
+ * @return a set containing the elements of the iterator
+ */
+ public static Set set(Iterator iterator, int expectedSize) {
+ return collection(new HashSet<>(HashUtil.capacity(expectedSize)), iterator);
+ }
+
+ /**
+ * Returns an iterator that only iterates over the given element.
+ *
+ * @param element
+ * the element to iterate over
+ * @param
+ * element type
+ *
+ * @return the iterator
+ */
+ public static Iterator singleton(T element) {
+ return new Iterator() {
+
+ private boolean hasNext = true;
+
+ @Override
+ public boolean hasNext() {
+ return hasNext;
+ }
+
+ @Override
+ public T next() {
+ if (hasNext) {
+ hasNext = false;
+ return element;
+ }
+
+ throw new NoSuchElementException();
+ }
+ };
+ }
+
+ /**
+ * Returns the number of elements returned by the iterator. Note that this consumes the iterator in the process.
+ *
+ * @param iterator
+ * the iterator whose elements should be counted
+ * @param
+ * element type
+ *
+ * @return the number of elements returned by the iterator
+ */
+ public static int size(Iterator iterator) {
+ int size = 0;
+ while (iterator.hasNext()) {
+ size++;
+ iterator.next();
+ }
+
+ return size;
+ }
+
+ /**
+ * Transforms the given iterator into a stream.
+ *
+ * @param iterator
+ * the source iterator
+ * @param
+ * element type
+ *
+ * @return the stream-based view on the iterator
+ */
+ public static Stream stream(Iterator iterator) {
+ return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
+ }
+
+ private static , T> C collection(C collection, Iterator iterator) {
+ while (iterator.hasNext()) {
+ collection.add(iterator.next());
+ }
+ return collection;
+ }
+}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/MappingCollection.java b/commons/util/src/main/java/net/automatalib/common/util/collection/MappingCollection.java
new file mode 100644
index 0000000000..9d7a459e4c
--- /dev/null
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/MappingCollection.java
@@ -0,0 +1,42 @@
+/* Copyright (C) 2013-2024 TU Dortmund University
+ * This file is part of AutomataLib, http://www.automatalib.net/.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.automatalib.common.util.collection;
+
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.function.Function;
+
+class MappingCollection extends AbstractCollection {
+
+ private final Collection delegate;
+ private final Function super D, ? extends R> mapping;
+
+ MappingCollection(Collection delegate, Function super D, ? extends R> mapping) {
+ this.delegate = delegate;
+ this.mapping = mapping;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return IteratorUtil.map(this.delegate.iterator(), this.mapping);
+ }
+
+ @Override
+ public int size() {
+ return this.delegate.size();
+ }
+}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/MappingIterator.java b/commons/util/src/main/java/net/automatalib/common/util/collection/MappingIterator.java
new file mode 100644
index 0000000000..138faf2233
--- /dev/null
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/MappingIterator.java
@@ -0,0 +1,45 @@
+/* Copyright (C) 2013-2024 TU Dortmund University
+ * This file is part of AutomataLib, http://www.automatalib.net/.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.automatalib.common.util.collection;
+
+import java.util.Iterator;
+import java.util.function.Function;
+
+class MappingIterator implements Iterator {
+
+ private final Iterator delegate;
+ private final Function super D, ? extends R> mapping;
+
+ MappingIterator(Iterator delegate, Function super D, ? extends R> mapping) {
+ this.delegate = delegate;
+ this.mapping = mapping;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return this.delegate.hasNext();
+ }
+
+ @Override
+ public R next() {
+ return this.mapping.apply(this.delegate.next());
+ }
+
+ @Override
+ public void remove() {
+ this.delegate.remove();
+ }
+}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/ReusableIterator.java b/commons/util/src/main/java/net/automatalib/common/util/collection/ReusableIterator.java
index 4332e0d561..57e6cdc6b2 100644
--- a/commons/util/src/main/java/net/automatalib/common/util/collection/ReusableIterator.java
+++ b/commons/util/src/main/java/net/automatalib/common/util/collection/ReusableIterator.java
@@ -19,8 +19,6 @@
import java.util.Iterator;
import java.util.List;
-import com.google.common.collect.AbstractIterator;
-
/**
* A utility class that allows to reuse an {@link Iterator}.
*
@@ -66,7 +64,7 @@ public Iterator iterator() {
return new CopyOnReadIterator(this.iterator);
}
- private class CopyOnReadIterator extends AbstractIterator {
+ private class CopyOnReadIterator implements Iterator {
private final Iterator source;
private int pos;
@@ -76,16 +74,17 @@ private class CopyOnReadIterator extends AbstractIterator {
}
@Override
- protected T computeNext() {
+ public boolean hasNext() {
+ return pos < frontier || source.hasNext();
+ }
+
+ @Override
+ public T next() {
if (pos < frontier) {
return cache.get(pos++);
}
- if (!source.hasNext()) {
- return endOfData();
- }
-
- T next = source.next();
+ final T next = source.next();
cache.add(next);
pos++;
frontier++;
diff --git a/commons/util/src/main/java/net/automatalib/common/util/collection/UnmodifiableListIterator.java b/commons/util/src/main/java/net/automatalib/common/util/collection/UnmodifiableListIterator.java
deleted file mode 100644
index 428831f259..0000000000
--- a/commons/util/src/main/java/net/automatalib/common/util/collection/UnmodifiableListIterator.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright (C) 2013-2024 TU Dortmund University
- * This file is part of AutomataLib, http://www.automatalib.net/.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package net.automatalib.common.util.collection;
-
-import java.util.ListIterator;
-
-import com.google.common.collect.ForwardingListIterator;
-
-/**
- * Wraps a given {@link ListIterator} so that any mutating operations throw an {@link UnsupportedOperationException}.
- *
- * @param
- * type of elements in the given iterator
- */
-public class UnmodifiableListIterator extends ForwardingListIterator {
-
- private final ListIterator extends T> delegate;
-
- public UnmodifiableListIterator(ListIterator extends T> delegate) {
- this.delegate = delegate;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- protected ListIterator delegate() {
- return (ListIterator) this.delegate;
- }
-
- @Override
- public final void remove() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public final void set(T t) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public final void add(T t) {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/exception/ExceptionUtil.java b/commons/util/src/main/java/net/automatalib/common/util/exception/ExceptionUtil.java
new file mode 100644
index 0000000000..31cb5e78a0
--- /dev/null
+++ b/commons/util/src/main/java/net/automatalib/common/util/exception/ExceptionUtil.java
@@ -0,0 +1,41 @@
+/* Copyright (C) 2013-2024 TU Dortmund University
+ * This file is part of AutomataLib, http://www.automatalib.net/.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.automatalib.common.util.exception;
+
+/**
+ * Utility methods for {@link Exception}s.
+ */
+public final class ExceptionUtil {
+
+ private ExceptionUtil() {
+ // prevent instantiation
+ }
+
+ /**
+ * Throws the given throwable if it is an unchecked exception.
+ *
+ * @param throwable
+ * the throwable to analyse
+ */
+ public static void throwIfUnchecked(Throwable throwable) {
+ if (throwable instanceof RuntimeException) {
+ throw (RuntimeException) throwable;
+ }
+ if (throwable instanceof Error) {
+ throw (Error) throwable;
+ }
+ }
+}
diff --git a/commons/util/src/main/java/net/automatalib/common/util/fixpoint/Worksets.java b/commons/util/src/main/java/net/automatalib/common/util/fixpoint/Worksets.java
index a7b3655ed1..dbc7ced2d0 100644
--- a/commons/util/src/main/java/net/automatalib/common/util/fixpoint/Worksets.java
+++ b/commons/util/src/main/java/net/automatalib/common/util/fixpoint/Worksets.java
@@ -18,11 +18,12 @@
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import net.automatalib.common.util.HashUtil;
import net.automatalib.common.util.Pair;
public final class Worksets {
@@ -35,7 +36,7 @@ public static R process(WorksetAlgorithm algorithm) {
final int expectedElementCount = algorithm.expectedElementCount();
final Deque queue = new ArrayDeque<>(expectedElementCount);
- final Set tracking = Sets.newHashSetWithExpectedSize(expectedElementCount);
+ final Set tracking = new HashSet<>(HashUtil.capacity(expectedElementCount));
final Collection initialElements = algorithm.initialize();
queue.addAll(initialElements);
@@ -62,8 +63,8 @@ public static R process(WorksetAlgorithm algorithm) {
public static Pair