diff --git a/CHANGES b/CHANGES index 6667d778de6f64137e4ee47918123c4149ce0b50..8d515562f2f518b4e5614af5417cbf06354b2dc4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,15 @@ +8.4.4 + +- Renamed andThen/compose methods for type-specific functions + to avoid potential ambiguous calls. + +- Now bulk colletion methods will try to use type-specific methods + if available. A side effect is that in case someone implemented + type-specific methods using the JDK version an infinite recursion + will happen. Thanks to C. Sean Young for this improvement. + +- New Pair and SortedPair implementations, both standard and type-specific. + 8.4.3 - Implemented andThen/compose methods for type-specific functions. @@ -10,6 +22,8 @@ - Static factory methods for immutable sets of primitive scalar types within a given range. +- .of() factory methods for lists and sets. + 8.4.2 - Big front-coded lists. diff --git a/README.md b/README.md index 3db97865262df393daa29971197d388ac6ce028d..01457ca303a8913a3ea33cc2f0de4b48f1200d82 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,9 @@ necessary classes. ## Building -You have to "make sources" to get the actual Java sources; finally, "ant jar" -and "ant javadoc" will generate the jar file and the API documentation. +You have to "make sources" to get the actual Java sources; finally, "ant +jar" will generate the jar file; "ant javadoc" will generate the API +documentation; "ant junit" will run the unit tests. The Java sources are generated using a C preprocessor. The `gencsource.sh` script reads in a driver file, that is, a Java source that uses some diff --git a/build.properties b/build.properties index dab8b7b0fa1edd29aa0ea4156f7c4b0b31835bbe..7e65b730609ef0bd71de76f0d43d9d04da1fc735 100644 --- a/build.properties +++ b/build.properties @@ -3,7 +3,7 @@ javadoc.base=/usr/share/javadoc build.sysclasspath=ignore -version=8.4.3 +version=8.4.4 dist=dist src=src diff --git a/build.xml b/build.xml index 9a6f7e44254c7ee1e4c9b352211a687a9b970b16..4440b03ebad1c576b68059f63be64917ad85ece7 100644 --- a/build.xml +++ b/build.xml @@ -4,7 +4,6 @@ <property file="build.properties"/> <property environment="env"/> - <property name="env.JAVA_HOME" value="/usr/java/latest"/> <!-- ************************************** WARNING: MAVEN SH*T ************************************** --> @@ -13,10 +12,8 @@ <property name="artifactId" value="fastutil" /> <property name="version" value="${version}" /> - <property name="maven-jar" value="${dist}/lib/${artifactId}-${version}.jar" /> - <!-- define artifacts' name, which follows the convention of Maven --> - + <property name="maven-jar" value="${dist}/lib/${artifactId}-${version}.jar" /> <property name="maven-javadoc-jar" value="${dist}/lib/${artifactId}-${version}-javadoc.jar" /> <property name="maven-sources-jar" value="${dist}/lib/${artifactId}-${version}-sources.jar" /> @@ -34,7 +31,6 @@ </target> <target name="osgi" depends="resolve,compile"> - <delete dir="${build}/*.class"/> <taskdef resource="aQute/bnd/ant/taskdef.properties" classpath="lib/bnd-2.4.0.jar"/> <bnd classpath="${build}" @@ -120,6 +116,7 @@ <target name="init"> <mkdir dir="${build}"/> <mkdir dir="${dist}/lib"/> + <mkdir dir="${reports}"/> <symlink link="${dist}/javadoc" resource="../${docs}" overwrite="true"/> </target> @@ -129,8 +126,7 @@ deprecation="on" optimize="on" destdir="${build}" - memoryInitialSize="800M" - memoryMaximumSize="800M" + memoryMaximumSize="2G" fork="yes" source="1.8" target="1.8"> @@ -143,9 +139,9 @@ debug="on" deprecation="on" optimize="on" + classpath="lib/junit-4.13.jar:lib" destdir="${build}" - memoryInitialSize="800M" - memoryMaximumSize="800M" + memoryMaximumSize="2G" fork="yes" source="1.8" target="1.8" @@ -154,7 +150,7 @@ <target name="jar" depends="compile"> <jar jarfile="fastutil-${version}.jar"> - <fileset dir="${build}" excludes="it/unimi/dsi/fastutil/*IndirectDoublePriorityQueue*"/> + <fileset dir="${build}"/> <manifest> <attribute name="Automatic-Module-Name" value="it.unimi.dsi.fastutil"/> </manifest> @@ -163,7 +159,7 @@ <target name="jar-tests" depends="compile"> <jar jarfile="fastutil-${version}.jar"> - <fileset dir="${build}" excludes="it/unimi/dsi/fastutil/*IndirectDoublePriorityQueue*"/> + <fileset dir="${build}"/> </jar> </target> @@ -182,8 +178,8 @@ public="on" source="1.8" windowtitle="fastutil ${version}" - additionalparam="-breakiterator -Xmaxwarns 10000" - maxmemory="800M" + additionalparam="-breakiterator -Xmaxwarns 10000 -tag "apiNote:a:API Notes:" -tag "implSpec:a:Implementation Specification:" -tag "implNote:a:Implementation Notes:\"" + maxmemory="2G" > <link href="${j2se.apiurl}"/> </javadoc> @@ -193,7 +189,11 @@ <junit printsummary="yes" fork="yes" haltonfailure="off" haltonerror="off"> <classpath location="${build}"/> <classpath location="${src}"/> - <jvmarg value="-Xmx1G" /> + <classpath location="lib/junit-4.13.jar"/> + <classpath location="lib/hamcrest-all-1.3.jar"/> + <jvmarg value="-Xmx3G" /> + + <assertions><enable/></assertions> <formatter type="xml"/> <formatter type="plain"/> diff --git a/drv/AbstractCollection.drv b/drv/AbstractCollection.drv index 33e6d5cfdc5028c1016437d40a3332fbb5629905..46487605961c4466077570def1e16bedae9b1e0e 100644 --- a/drv/AbstractCollection.drv +++ b/drv/AbstractCollection.drv @@ -19,6 +19,10 @@ package PACKAGE; import java.util.AbstractCollection; +#if KEYS_PRIMITIVE +import java.util.Collection; +#endif + /** An abstract class providing basic methods for collections implementing a type-specific interface. * * <p>In particular, this class provide {@link #iterator()}, {@code add()}, {@link #remove(Object)} and @@ -134,6 +138,19 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC extends AbstractCollection if (add(i.NEXT_KEY())) retVal = true; return retVal; } + + /** {@inheritDoc} + * + * <p>This implementation delegates to the type-specific version if given a type-specific + * collection, otherwise is uses the implementation from {@link AbstractCollection}. + */ + @Override + public boolean addAll(final Collection<? extends KEY_CLASS> c) { + if (c instanceof COLLECTION) { + return addAll((COLLECTION) c); + } + return super.addAll(c); + } @Override public boolean containsAll(final COLLECTION c) { @@ -141,6 +158,19 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC extends AbstractCollection if (! contains(i.NEXT_KEY())) return false; return true; } + + /** {@inheritDoc} + * + * <p>This implementation delegates to the type-specific version if given a type-specific + * collection, otherwise is uses the implementation from {@link AbstractCollection}. + */ + @Override + public boolean containsAll(final Collection<?> c) { + if (c instanceof COLLECTION) { + return containsAll((COLLECTION) c); + } + return super.containsAll(c); + } @Override public boolean removeAll(final COLLECTION c) { @@ -150,6 +180,19 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC extends AbstractCollection return retVal; } + /** {@inheritDoc} + * + * <p>This implementation delegates to the type-specific version if given a type-specific + * collection, otherwise is uses the implementation from {@link AbstractCollection}. + */ + @Override + public boolean removeAll(final Collection<?> c) { + if (c instanceof COLLECTION) { + return removeAll((COLLECTION) c); + } + return super.removeAll(c); + } + @Override public boolean retainAll(final COLLECTION c) { boolean retVal = false; @@ -160,6 +203,19 @@ public abstract class ABSTRACT_COLLECTION KEY_GENERIC extends AbstractCollection } return retVal; } + + /** {@inheritDoc} + * + * <p>This implementation delegates to the type-specific version if given a type-specific + * collection, otherwise is uses the implementation from {@link AbstractCollection}. + */ + @Override + public boolean retainAll(final Collection<?> c) { + if (c instanceof COLLECTION) { + return retainAll((COLLECTION) c); + } + return super.retainAll(c); + } #endif @Override diff --git a/drv/AbstractList.drv b/drv/AbstractList.drv index 6924fa5a2239b6c19be95fe9d9fc4b67e45923a8..f2df83a332116918f6744c8e54690c1102e509f8 100644 --- a/drv/AbstractList.drv +++ b/drv/AbstractList.drv @@ -96,6 +96,11 @@ public abstract class ABSTRACT_LIST KEY_GENERIC extends ABSTRACT_COLLECTION KEY_ /** Adds all of the elements in the specified collection to this list (optional operation). */ @Override public boolean addAll(int index, final Collection<? extends KEY_GENERIC_CLASS> c) { +#if KEYS_PRIMITIVE + if (c instanceof COLLECTION) { + return addAll(index, (COLLECTION) c); + } +#endif ensureIndex(index); final Iterator<? extends KEY_GENERIC_CLASS> i = c.iterator(); final boolean retVal = i.hasNext(); diff --git a/drv/AbstractSet.drv b/drv/AbstractSet.drv index 9ab081a74988fc7e473c50707958fc39c043ce4b..93068dc0f7bbf30d8324662ba7de0c3e144cb820 100644 --- a/drv/AbstractSet.drv +++ b/drv/AbstractSet.drv @@ -41,6 +41,11 @@ public abstract class ABSTRACT_SET KEY_GENERIC extends ABSTRACT_COLLECTION KEY_G Set<?> s = (Set<?>) o; if (s.size() != size()) return false; +#if KEYS_PRIMITIVE + if (s instanceof SET) { + return containsAll((SET) s); + } +#endif return containsAll(s); } diff --git a/drv/ArrayList.drv b/drv/ArrayList.drv index bf68ee438aaadd0238e598b15cdf84c6617d3310..b24e71fa598487e71d8d831f22d32ffc6bd847db 100644 --- a/drv/ArrayList.drv +++ b/drv/ArrayList.drv @@ -283,6 +283,18 @@ public class ARRAY_LIST KEY_GENERIC extends ABSTRACT_LIST KEY_GENERIC implements } + /** Creates an array list using a list of elements. + * + * @param init a list of elements that will be used to initialize the list. + * @return a new array list containing the given elements. + */ + + @SafeVarargs + public static KEY_GENERIC ARRAY_LIST KEY_GENERIC of(final KEY_GENERIC_TYPE... init) { + return wrap(init); + } + + /** Ensures that this array list can contain the given number of entries without resizing. * * @param capacity the new minimum capacity for this array list. diff --git a/drv/BigArrayBigList.drv b/drv/BigArrayBigList.drv index 7a1733172fc1cae4096a803c1b1967f1d07db164..53c6ee9b3426667b906dc5a3d0c6755ade4afb54 100644 --- a/drv/BigArrayBigList.drv +++ b/drv/BigArrayBigList.drv @@ -262,6 +262,18 @@ public class BIG_ARRAY_BIG_LIST KEY_GENERIC extends ABSTRACT_BIG_LIST KEY_GENERI } + /** Creates a big array list using a list of elements. + * + * @param init a list of elements that will be used to initialize the big list. + * @return a new big-array big list containing the given elements. + */ + + @SafeVarargs + public static KEY_GENERIC BIG_ARRAY_BIG_LIST KEY_GENERIC of(final KEY_GENERIC_TYPE... init) { + return wrap(BigArrays.wrap(init)); + } + + /** Ensures that this big-array big list can contain the given number of entries without resizing. * * @param capacity the new minimum capacity for this big-array big list. diff --git a/drv/BigArrays.drv b/drv/BigArrays.drv index af9485017fcd7290cc7d97dd735afc9f5913dd9b..2684759bacf366054c5fddd901a3d8cc360e513e 100644 --- a/drv/BigArrays.drv +++ b/drv/BigArrays.drv @@ -57,7 +57,7 @@ import it.unimi.dsi.fastutil.bytes.ByteBigArrays; /** A class providing static methods and objects that do useful things with {@linkplain BigArrays big arrays}. * - * <p><strong>WARNING</strong>: as of 8.3.0, many methods such as {@link #length()} have been moved to + * <p><strong>WARNING</strong>: as of 8.3.0, many methods such as {@code length()} have been moved to * {@link BigArrays}, as they can be imported statically in a more convenient way. * * <p>Note that {@link it.unimi.dsi.fastutil.io.BinIO} and {@link it.unimi.dsi.fastutil.io.TextIO} diff --git a/drv/Function.drv b/drv/Function.drv index d21798a720cbd53c7834edd4adffe0facd4e7f4c..5c0351b76ea3c139d083f1362c2763c34252f5d7 100644 --- a/drv/Function.drv +++ b/drv/Function.drv @@ -256,10 +256,10 @@ public interface FUNCTION KEY_VALUE_GENERIC extends Function<KEY_GENERIC_CLASS, #define COMPOSITION(K_C, V_C, T_C, T_P, G_A, G_B, T_G, K_T_G, V_T_G, T_V_G, T_K_G) \ - default T_G PACKAGE.FUNCTION_NAME(K_C, T_C) K_T_G andThen(VALUE_PACKAGE.FUNCTION_NAME(V_C, T_C) V_T_G after) { \ + default T_G PACKAGE.FUNCTION_NAME(K_C, T_C) K_T_G andThen ## T_C(VALUE_PACKAGE.FUNCTION_NAME(V_C, T_C) V_T_G after) { \ return k -> after.G_A(GET_VALUE(k)); \ } \ - default T_G it.unimi.dsi.fastutil.T_P.FUNCTION_NAME(T_C, V_C) T_V_G compose(it.unimi.dsi.fastutil.T_P.FUNCTION_NAME(T_C, K_C) T_K_G before) { \ + default T_G it.unimi.dsi.fastutil.T_P.FUNCTION_NAME(T_C, V_C) T_V_G compose ## T_C(it.unimi.dsi.fastutil.T_P.FUNCTION_NAME(T_C, K_C) T_K_G before) { \ return k -> GET_VALUE(before.G_B(k)); \ } @@ -273,4 +273,4 @@ COMPOSITION(KEY_TYPE_CAP, VALUE_TYPE_CAP, Double, doubles, GET_AFTER(Double), ge COMPOSITION(KEY_TYPE_CAP, VALUE_TYPE_CAP, Object, objects, get, GET_BEFORE, <T>, K_T_G, V_T_G, T_V_G, T_K_G) COMPOSITION(KEY_TYPE_CAP, VALUE_TYPE_CAP, Reference, objects, get, GET_BEFORE, <T>, K_T_G, V_T_G, T_V_G, T_K_G) -} \ No newline at end of file +} diff --git a/drv/ImmutablePair.drv b/drv/ImmutablePair.drv new file mode 100644 index 0000000000000000000000000000000000000000..756dbb3b08bdbc6eeaed02bfd7fe65c1767b2d59 --- /dev/null +++ b/drv/ImmutablePair.drv @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2002-2020 Sebastiano Vigna + * + * 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 PACKAGE; + +/** A type-specific immutable {@link it.unimi.dsi.fastutil.Pair Pair}; provides some additional methods that use polymorphism to avoid (un)boxing. */ + +public class IMMUTABLE_PAIR KEY_VALUE_GENERIC implements PAIR KEY_VALUE_GENERIC, java.io.Serializable { + private static final long serialVersionUID = 0L; + + protected final KEY_GENERIC_TYPE left; + protected final VALUE_GENERIC_TYPE right; + + /** Creates a new type-specific immutable {@link it.unimi.dsi.fastutil.Pair Pair} with given left and right value. + * @param left the left value. + * @param right the right value. + */ + public IMMUTABLE_PAIR(final KEY_GENERIC_TYPE left, final VALUE_GENERIC_TYPE right) { + this.left = left; + this.right = right; + } + + /** Returns a new type-specific immutable {@link it.unimi.dsi.fastutil.Pair Pair} with given left and right value. + * @param left the left value. + * @param right the right value. + * + * @implNote This factory method delegates to the constructor. + */ + public static KEY_VALUE_GENERIC IMMUTABLE_PAIR KEY_VALUE_GENERIC of(final KEY_GENERIC_TYPE left, final VALUE_GENERIC_TYPE right) { + return new IMMUTABLE_PAIR KEY_VALUE_GENERIC(left, right); + } + + @Override + public KEY_GENERIC_TYPE PAIR_LEFT() { + return left; + } + + @Override + public VALUE_GENERIC_TYPE PAIR_RIGHT() { + return right; + } + + @Override + @SuppressWarnings("rawtypes") + public boolean equals(Object other) { + if (other == null) return false; + +#if KEYS_PRIMITIVE || VALUES_PRIMITIVE + if (other instanceof PAIR) { + return + +#if KEY_CLASS_Object + java.util.Objects.equals(left, ((PAIR)other).PAIR_LEFT()) +#else + left == ((PAIR)other).PAIR_LEFT() +#endif +#if VALUE_CLASS_Object + && java.util.Objects.equals(right, ((PAIR)other).PAIR_RIGHT()); +#else + && right == ((PAIR)other).PAIR_RIGHT(); +#endif + } +#endif + + if (other instanceof it.unimi.dsi.fastutil.Pair) { + return +#if KEY_CLASS_Reference + left == ((it.unimi.dsi.fastutil.Pair)other).left() +#else + java.util.Objects.equals(KEY2OBJ(left), ((it.unimi.dsi.fastutil.Pair)other).left()) +#endif +#if VALUE_CLASS_Reference + && right == ((it.unimi.dsi.fastutil.Pair)other).right(); +#else + && java.util.Objects.equals(VALUE2OBJ(right), ((it.unimi.dsi.fastutil.Pair)other).right()); +#endif + } + + return false; + } + + public int hashCode() { + return KEY2JAVAHASH(left) * 19 + VALUE2JAVAHASH(right); + } + + /** Returns a string representation of this pair in the form <<var>l</var>,<var>r</var>>. + * + * @return a string representation of this pair in the form <<var>l</var>,<var>r</var>>. + */ + @Override + public String toString() { + return "<" + PAIR_LEFT() + "," + PAIR_RIGHT() + ">"; + } +} \ No newline at end of file diff --git a/drv/ImmutableSortedPair.drv b/drv/ImmutableSortedPair.drv new file mode 100644 index 0000000000000000000000000000000000000000..9bf0be6d0afa9ad913348802665bc0143d93de95 --- /dev/null +++ b/drv/ImmutableSortedPair.drv @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2002-2020 Sebastiano Vigna + * + * 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 PACKAGE; + +/** A type-specific immutable {@link it.unimi.dsi.fastutil.SortedPair SortedPair}; provides some additional methods that use polymorphism to avoid (un)boxing. */ + +#if KEYS_PRIMITIVE +public class IMMUTABLE_SORTED_PAIR extends IMMUTABLE_PAIR implements SORTED_PAIR, java.io.Serializable { +#else +public class IMMUTABLE_SORTED_PAIR <K extends Comparable<K>> extends IMMUTABLE_PAIR <K, K> implements it.unimi.dsi.fastutil.SortedPair<K>, java.io.Serializable { +#endif + private static final long serialVersionUID = 0L; + + private IMMUTABLE_SORTED_PAIR(final KEY_GENERIC_TYPE left, final KEY_GENERIC_TYPE right) { + super(left, right); + } + + /** Returns a new type-specific immutable {@link it.unimi.dsi.fastutil.SortedPair SortedPair} with given left and right value. + * + * <p>Note that if {@code left} and {@code right} are in the wrong order, they will be exchanged. + * + * @param left the left value. + * @param right the right value. + * + * @implNote This factory method delegates to the constructor. + */ +#if KEYS_PRIMITIVE + public static IMMUTABLE_SORTED_PAIR of(final KEY_GENERIC_TYPE left, final KEY_GENERIC_TYPE right) { + if (left <= right) return new IMMUTABLE_SORTED_PAIR(left, right); + else return new IMMUTABLE_SORTED_PAIR(right, left); +#else + public static <K extends Comparable<K>> IMMUTABLE_SORTED_PAIR <K> of(final KEY_GENERIC_TYPE left, final KEY_GENERIC_TYPE right) { + if (left.compareTo(right) <= 0) return new IMMUTABLE_SORTED_PAIR <K>(left, right); + else return new IMMUTABLE_SORTED_PAIR <K>(right, left); +#endif + } + + @Override + @SuppressWarnings("rawtypes") + public boolean equals(Object other) { + if (other == null) return false; + +#if KEYS_PRIMITIVE || VALUES_PRIMITIVE + if (other instanceof SORTED_PAIR) { + return + +#if KEY_CLASS_Object + java.util.Objects.equals(left, ((SORTED_PAIR)other).PAIR_LEFT()) +#else + left == ((SORTED_PAIR)other).PAIR_LEFT() +#endif +#if VALUE_CLASS_Object + && java.util.Objects.equals(right, ((SORTED_PAIR)other).PAIR_RIGHT()); +#else + && right == ((SORTED_PAIR)other).PAIR_RIGHT(); +#endif + } +#endif + + if (other instanceof it.unimi.dsi.fastutil.SortedPair) { + return +#if KEY_CLASS_Reference + left == ((it.unimi.dsi.fastutil.SortedPair)other).left() +#else + java.util.Objects.equals(KEY2OBJ(left), ((it.unimi.dsi.fastutil.SortedPair)other).left()) +#endif +#if VALUE_CLASS_Reference + && right == ((it.unimi.dsi.fastutil.SortedPair)other).right(); +#else + && java.util.Objects.equals(VALUE2OBJ(right), ((it.unimi.dsi.fastutil.SortedPair)other).right()); +#endif + } + + return false; + } + + /** Returns a string representation of this sorted pair in the form {<var>l</var>,<var>r</var>}. + * + * @return a string representation of this pair sorted in the form {<var>l</var>,<var>r</var>}. + */ + @Override + public String toString() { + return "{" + PAIR_LEFT() + "," + PAIR_RIGHT() + "}"; + } +} \ No newline at end of file diff --git a/drv/Iterables.drv b/drv/Iterables.drv index c04bb1e2c0fb6b8b6530a83858eace5ec40dc56e..9a87009d603b2578439dd4c199392e290608de1b 100644 --- a/drv/Iterables.drv +++ b/drv/Iterables.drv @@ -31,7 +31,7 @@ public final class ITERABLES { * @param iterable an iterable. * @return the number of elements returned by {@code iterable}. */ - public static KEY_GENERIC long size(final KEY_ITERABLE KEY_GENERIC iterable) { + public static KEY_GENERIC long size(final STD_KEY_ITERABLE KEY_GENERIC iterable) { long c = 0; for (@SuppressWarnings("unused") final KEY_GENERIC_TYPE dummy : iterable) c++; return c; diff --git a/drv/List.drv b/drv/List.drv index efb8a2c42b2e944ba85a8c29b1e870b3d294295f..de9d00a37d50864d9568951a9b0ab9c39689ba5c 100644 --- a/drv/List.drv +++ b/drv/List.drv @@ -315,7 +315,18 @@ public interface LIST KEY_GENERIC extends List<KEY_GENERIC_CLASS>, COLLECTION KE #endif -#if defined KEY_COMPARATOR && KEYS_PRIMITIVE + /** Creates an array list using a list of elements. + * + * @param init a list of elements that will be used to initialize the list. + * @return a new array list containing the given elements. + */ + + @SafeVarargs + public static KEY_GENERIC LIST KEY_GENERIC of(final KEY_GENERIC_TYPE... init) { + return ARRAY_LIST.wrap(init); + } + +#if defined(KEY_COMPARATOR) && KEYS_PRIMITIVE /** {@inheritDoc} * @deprecated Please use the corresponding type-specific method instead. */ @@ -330,11 +341,11 @@ public interface LIST KEY_GENERIC extends List<KEY_GENERIC_CLASS>, COLLECTION KE * <p>Pass {@code null} to sort using natural ordering. * @see List#sort(java.util.Comparator) * - * @implSpec The default implementation dumps the elements into an array using + * @implNote The default implementation dumps the elements into an array using * {@link #toArray()}, sorts the array, then replaces all elements using the * {@link #setElements} function. * - * @implneNote It is possible for this method to call {@link #unstableSort} if it can + * <p>It is possible for this method to call {@link #unstableSort} if it can * determine that the results of a stable and unstable sort are completely equivalent. * This means if you override {@link #unstableSort}, it should <em>not</em> call this * method unless you override this method as well. @@ -382,7 +393,7 @@ public interface LIST KEY_GENERIC extends List<KEY_GENERIC_CLASS>, COLLECTION KE * <p>Unless a subclass specifies otherwise, the results of the method if the list is * concurrently modified during the sort are unspecified. * - * @implSpec The default implementation dumps the elements into an array using + * @implNote The default implementation dumps the elements into an array using * {@link #toArray()}, sorts the array, then replaces all elements using the * {@link #setElements} function. * @@ -408,7 +419,7 @@ public interface LIST KEY_GENERIC extends List<KEY_GENERIC_CLASS>, COLLECTION KE * <p>Unless a subclass specifies otherwise, the results of the method if the list is * concurrently modified during the sort are unspecified. * - * @implSpec The default implementation dumps the elements into an array using + * @implNote The default implementation dumps the elements into an array using * {@link #toArray()}, sorts the array, then replaces all elements using the * {@link #setElements} function. * diff --git a/drv/MutablePair.drv b/drv/MutablePair.drv new file mode 100644 index 0000000000000000000000000000000000000000..d543f797e3e97b0ddbb98bc2564cdd654883bd39 --- /dev/null +++ b/drv/MutablePair.drv @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2002-2020 Sebastiano Vigna + * + * 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 PACKAGE; + +/** A type-specific mutable {@link it.unimi.dsi.fastutil.Pair Pair}; provides some additional methods that use polymorphism to avoid (un)boxing. */ + +public class MUTABLE_PAIR KEY_VALUE_GENERIC implements PAIR KEY_VALUE_GENERIC, java.io.Serializable { + private static final long serialVersionUID = 0L; + + protected KEY_GENERIC_TYPE left; + protected VALUE_GENERIC_TYPE right; + + /** Creates a new type-specific mutable {@link it.unimi.dsi.fastutil.Pair Pair} with given left and right value. + * @param left the left value. + * @param right the right value. + */ + public MUTABLE_PAIR(final KEY_GENERIC_TYPE left, final VALUE_GENERIC_TYPE right) { + this.left = left; + this.right = right; + } + + /** Returns a new type-specific mutable {@link it.unimi.dsi.fastutil.Pair Pair} with given left and right value. + * @param left the left value. + * @param right the right value. + * + * @implNote This factory method delegates to the constructor. + */ + public static KEY_VALUE_GENERIC MUTABLE_PAIR KEY_VALUE_GENERIC of(final KEY_GENERIC_TYPE left, final VALUE_GENERIC_TYPE right) { + return new MUTABLE_PAIR KEY_VALUE_GENERIC(left, right); + } + + @Override + public KEY_GENERIC_TYPE PAIR_LEFT() { + return left; + } + + public MUTABLE_PAIR KEY_VALUE_GENERIC left(final KEY_GENERIC_TYPE l) { + left = l; + return this; + } + + @Override + public VALUE_GENERIC_TYPE PAIR_RIGHT() { + return right; + } + + public MUTABLE_PAIR KEY_VALUE_GENERIC right(final VALUE_GENERIC_TYPE r) { + right = r; + return this; + } + + + @Override + @SuppressWarnings("rawtypes") + public boolean equals(Object other) { + if (other == null) return false; + +#if KEYS_PRIMITIVE || VALUES_PRIMITIVE + if (other instanceof PAIR) { + return + +#if KEY_CLASS_Object + java.util.Objects.equals(left, ((PAIR)other).PAIR_LEFT()) +#else + left == ((PAIR)other).PAIR_LEFT() +#endif +#if VALUE_CLASS_Object + && java.util.Objects.equals(right, ((PAIR)other).PAIR_RIGHT()); +#else + && right == ((PAIR)other).PAIR_RIGHT(); +#endif + } +#endif + + if (other instanceof it.unimi.dsi.fastutil.Pair) { + return +#if KEY_CLASS_Reference + left == ((it.unimi.dsi.fastutil.Pair)other).left() +#else + java.util.Objects.equals(KEY2OBJ(left), ((it.unimi.dsi.fastutil.Pair)other).left()) +#endif +#if VALUE_CLASS_Reference + && right == ((it.unimi.dsi.fastutil.Pair)other).right(); +#else + && java.util.Objects.equals(VALUE2OBJ(right), ((it.unimi.dsi.fastutil.Pair)other).right()); +#endif + } + + return false; + } + + public int hashCode() { + return KEY2JAVAHASH(left) * 19 + VALUE2JAVAHASH(right); + } + + /** Returns a string representation of this pair in the form <<var>l</var>,<var>r</var>>. + * + * @return a string representation of this pair in the form <<var>l</var>,<var>r</var>>. + */ + @Override + public String toString() { + return "<" + PAIR_LEFT() + "," + PAIR_RIGHT() + ">"; + } +} diff --git a/drv/OpenHashMap.drv b/drv/OpenHashMap.drv index 8c270e55bd8ae271042650fbfd99d7a376d9a46b..b86944d30dd642a678593bcf6928da2806fc7856 100644 --- a/drv/OpenHashMap.drv +++ b/drv/OpenHashMap.drv @@ -76,6 +76,10 @@ import it.unimi.dsi.fastutil.objects.ObjectSortedSet; * methods} lets you control the size of the table; this is particularly useful * if you reuse instances of this class. * + * <p>Entries returned by the type-specific {@link #entrySet()} method implement + * the suitable type-specific {@link it.unimi.dsi.fastutil.Pair Pair} interface; + * only values are mutable. + * * <p>Iterators generated by this map will enumerate pairs in the same order in which they * have been added to the map (addition of pairs whose key is already present * in the map does not change the iteration order). Note that this order has nothing in common with the natural @@ -135,6 +139,10 @@ import it.unimi.dsi.fastutil.objects.ObjectIterator; * methods} lets you control the size of the table; this is particularly useful * if you reuse instances of this class. * + * <p>Entries returned by the type-specific {@link #entrySet()} method implement + * the suitable type-specific {@link it.unimi.dsi.fastutil.Pair Pair} interface; + * only values are mutable. + * * @see Hash * @see HashCommon */ @@ -160,6 +168,10 @@ public class OPEN_HASH_MAP KEY_VALUE_GENERIC extends ABSTRACT_MAP KEY_VALUE_GENE * methods} lets you control the size of the table; this is particularly useful * if you reuse instances of this class. * + * <p>Entries returned by the type-specific {@link #entrySet()} method implement + * the suitable type-specific {@link it.unimi.dsi.fastutil.Pair Pair} interface; + * only values are mutable. + * * @see Hash * @see HashCommon */ @@ -1266,7 +1278,7 @@ public class OPEN_HASH_MAP KEY_VALUE_GENERIC extends ABSTRACT_MAP KEY_VALUE_GENE * is necessary so that calls to {@link java.util.Map.Entry#setValue(Object)} are reflected in * the map */ - final class MapEntry implements MAP.Entry KEY_VALUE_GENERIC, Map.Entry<KEY_GENERIC_CLASS, VALUE_GENERIC_CLASS> { + final class MapEntry implements MAP.Entry KEY_VALUE_GENERIC, Map.Entry<KEY_GENERIC_CLASS, VALUE_GENERIC_CLASS>, PAIR KEY_VALUE_GENERIC { // The table index this entry refers to, or -1 if this entry has been deleted. int index; @@ -1281,11 +1293,21 @@ public class OPEN_HASH_MAP KEY_VALUE_GENERIC extends ABSTRACT_MAP KEY_VALUE_GENE return key[index]; } + @Override + public KEY_GENERIC_TYPE PAIR_LEFT() { + return key[index]; + } + @Override public VALUE_GENERIC_TYPE ENTRY_GET_VALUE() { return value[index]; } + @Override + public VALUE_GENERIC_TYPE PAIR_RIGHT() { + return value[index]; + } + @Override public VALUE_GENERIC_TYPE setValue(final VALUE_GENERIC_TYPE v) { final VALUE_GENERIC_TYPE oldValue = value[index]; @@ -1293,6 +1315,12 @@ public class OPEN_HASH_MAP KEY_VALUE_GENERIC extends ABSTRACT_MAP KEY_VALUE_GENE return oldValue; } + @Override + public PAIR KEY_VALUE_GENERIC right(final VALUE_GENERIC_TYPE v) { + value[index] = v; + return this; + } + #if KEYS_PRIMITIVE /** {@inheritDoc} * @deprecated Please use the corresponding type-specific method instead. */ diff --git a/drv/OpenHashSet.drv b/drv/OpenHashSet.drv index ac7c8756d370f98f364dbccf49e2bd8e643cbdd3..eb7f5db1abfa5b1487e9894ae4695d7332758473 100644 --- a/drv/OpenHashSet.drv +++ b/drv/OpenHashSet.drv @@ -557,6 +557,7 @@ public class OPEN_HASH_SET KEY_GENERIC extends ABSTRACT_SET KEY_GENERIC implemen public OPEN_HASH_SET(final KEY_GENERIC_TYPE[] a, final STRATEGY KEY_SUPER_GENERIC strategy) { this(a, DEFAULT_LOAD_FACTOR, strategy); } + #else /** Creates a new hash set with {@link Hash#DEFAULT_LOAD_FACTOR} as load factor * copying the elements of an array. @@ -567,6 +568,17 @@ public class OPEN_HASH_SET KEY_GENERIC extends ABSTRACT_SET KEY_GENERIC implemen public OPEN_HASH_SET(final KEY_GENERIC_TYPE[] a) { this(a, DEFAULT_LOAD_FACTOR); } + + /** Creates a new hash set with {@link Hash#DEFAULT_LOAD_FACTOR} as load factor + * using a list of elements. + * + * @param a a list of elements that will be used to initialize the new hash set. + */ + + @SafeVarargs + public static KEY_GENERIC OPEN_HASH_SET KEY_GENERIC of(final KEY_GENERIC_TYPE... a) { + return new OPEN_HASH_SET KEY_GENERIC(a, DEFAULT_LOAD_FACTOR); + } #endif diff --git a/drv/Pair.drv b/drv/Pair.drv new file mode 100644 index 0000000000000000000000000000000000000000..32550bb8e2b4682efaafaf91f39a4bf831633570 --- /dev/null +++ b/drv/Pair.drv @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2002-2020 Sebastiano Vigna + * + * 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 PACKAGE; + +/** A type-specific {@link it.unimi.dsi.fastutil.Pair Pair}; provides some additional methods that use polymorphism to avoid (un)boxing. */ + +public interface PAIR KEY_VALUE_GENERIC extends it.unimi.dsi.fastutil.Pair<KEY_GENERIC_CLASS, VALUE_GENERIC_CLASS> { +#if KEYS_PRIMITIVE + + /** + * Returns the left element of this pair. + * + * @return the left element of this pair. + */ + public KEY_TYPE PAIR_LEFT(); + + /** {@inheritDoc} + * @deprecated Please use the corresponding type-specific method instead. + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public default KEY_CLASS left() { + return KEY2OBJ(PAIR_LEFT()); + } + + /** + * Sets the left element of this pair (optional operation). + * + * @param l a new value for the left element. + * + * @implNote This implementation throws an {@link UnsupportedOperationException}. + */ + public default PAIR KEY_VALUE_GENERIC left(final KEY_TYPE l) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} + * @deprecated Please use the corresponding type-specific method instead. + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public default PAIR KEY_VALUE_GENERIC left(final KEY_CLASS l) { + return left(KEY_CLASS2TYPE(l)); + } + + /** + * Returns the left element of this pair. + * + * @return the left element of this pair. + * + * @implNote This implementation delegates to {@link #left()}. + * + */ + public default KEY_TYPE PAIR_FIRST() { + return PAIR_LEFT(); + } + + /** {@inheritDoc} + * @deprecated Please use the corresponding type-specific method instead. + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public default KEY_CLASS first() { + return KEY2OBJ(PAIR_FIRST()); + } + + /** + * Sets the left element of this pair (optional operation). + * + * @param l a new value for the left element. + * + * @implNote This implementation delegates to {@link #left(Object)}. + */ + public default PAIR KEY_VALUE_GENERIC first(final KEY_TYPE l) { + return left(l); + } + + /** {@inheritDoc} + * @deprecated Please use the corresponding type-specific method instead. + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public default PAIR KEY_VALUE_GENERIC first(final KEY_CLASS l) { + return first(KEY_CLASS2TYPE(l)); + } + + /** + * Returns the left element of this pair. + * + * @return the left element of this pair. + * + * @implNote This implementation delegates to {@link #left()}. + * + */ + public default KEY_TYPE PAIR_KEY() { + return PAIR_FIRST(); + } + + /** {@inheritDoc} + * @deprecated Please use the corresponding type-specific method instead. + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public default KEY_CLASS key() { + return KEY2OBJ(PAIR_KEY()); + } + + /** + * Sets the left element of this pair (optional operation). + * + * @param l a new value for the left element. + * + * @implNote This implementation delegates to {@link #left(Object)}. + */ + public default PAIR KEY_VALUE_GENERIC key(final KEY_TYPE l) { + return left(l); + } + + @Deprecated + public default PAIR KEY_VALUE_GENERIC key(KEY_CLASS l) { + return key(KEY_CLASS2TYPE(l)); + } + +#endif + +#if VALUES_PRIMITIVE + + /** + * Returns the right element of this pair. + * + * @return the right element of this pair. + */ + public VALUE_TYPE PAIR_RIGHT(); + + /** {@inheritDoc} + * @deprecated Please use the corresponding type-specific method instead. + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public default VALUE_CLASS right() { + return VALUE2OBJ(PAIR_RIGHT()); + } + + + /** + * Sets the right element of this pair (optional operation). + * + * @param r a new value for the right element. + * + * @implNote This implementation throws an {@link UnsupportedOperationException}. + */ + public default PAIR KEY_VALUE_GENERIC right(final VALUE_TYPE r) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} + * @deprecated Please use the corresponding type-specific method instead. + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public default PAIR KEY_VALUE_GENERIC right(final VALUE_CLASS l) { + return right(VALUE_CLASS2TYPE(l)); + } + + /** + * Returns the right element of this pair. + * + * @return the right element of this pair. + * + * @implNote This implementation delegates to {@link #right()}. + * + */ + public default VALUE_TYPE PAIR_SECOND() { + return PAIR_RIGHT(); + } + + /** {@inheritDoc} + * @deprecated Please use the corresponding type-specific method instead. + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public default VALUE_CLASS second() { + return VALUE2OBJ(PAIR_SECOND()); + } + + /** + * Sets the right element of this pair (optional operation). + * + * @param r a new value for the right element. + * + * @implNote This implementation delegates to {@link #right(Object)}. + */ + public default PAIR KEY_VALUE_GENERIC second(final VALUE_TYPE r) { + return right(r); + } + + /** {@inheritDoc} + * @deprecated Please use the corresponding type-specific method instead. + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public default PAIR KEY_VALUE_GENERIC second(final VALUE_CLASS l) { + return second(VALUE_CLASS2TYPE(l)); + } + + /** + * Returns the right element of this pair. + * + * @return the right element of this pair. + * + * @implNote This implementation delegates to {@link #right()}. + * + */ + public default VALUE_TYPE PAIR_VALUE() { + return PAIR_RIGHT(); + } + + /** {@inheritDoc} + * @deprecated Please use the corresponding type-specific method instead. + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public default VALUE_CLASS value() { + return VALUE2OBJ(PAIR_VALUE()); + } + + /** + * Sets the right element of this pair (optional operation). + * + * @param r a new value for the right element. + * + * @implNote This implementation delegates to {@link #right(Object)}. + */ + public default PAIR KEY_VALUE_GENERIC value(final VALUE_TYPE r) { + return right(r); + } + + /** {@inheritDoc} + * @deprecated Please use the corresponding type-specific method instead. + */ + @SuppressWarnings("deprecation") + @Deprecated + @Override + public default PAIR KEY_VALUE_GENERIC value(final VALUE_CLASS l) { + return value(VALUE_CLASS2TYPE(l)); + } + + +#endif + + /** Returns a new type-specific immutable {@link it.unimi.dsi.fastutil.Pair Pair} with given left and right value. + * @param left the left value. + * @param right the right value. + */ + public static KEY_VALUE_GENERIC PAIR KEY_VALUE_GENERIC of(final KEY_GENERIC_TYPE left, final VALUE_GENERIC_TYPE right) { + return new IMMUTABLE_PAIR KEY_VALUE_GENERIC(left, right); + } +} diff --git a/drv/Set.drv b/drv/Set.drv index 135f14cc48d5290ad31d6f4936c207fb8863a29f..acfd208159d4970b794a6aed01f0e1cc8bd2fd45 100644 --- a/drv/Set.drv +++ b/drv/Set.drv @@ -95,4 +95,15 @@ public interface SET KEY_GENERIC extends COLLECTION KEY_GENERIC, Set<KEY_GENERIC } #endif + + /** Creates a new set using a list of elements. + * + * @param a a list of elements that will be used to initialize the new set. + */ + + @SafeVarargs + public static KEY_GENERIC SET KEY_GENERIC of(final KEY_GENERIC_TYPE... a) { + return new OPEN_HASH_SET KEY_GENERIC(a); + } + } diff --git a/drv/SortedPair.drv b/drv/SortedPair.drv new file mode 100644 index 0000000000000000000000000000000000000000..23d0ffd98ad7fd027376272e5510d664deb18874 --- /dev/null +++ b/drv/SortedPair.drv @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2002-2020 Sebastiano Vigna + * + * 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 PACKAGE; + +/** A type-specific immutable {@link it.unimi.dsi.fastutil.SortedPair SortedPair}. */ + +#if KEYS_PRIMITIVE +public interface SORTED_PAIR extends PAIR, it.unimi.dsi.fastutil.SortedPair<KEY_CLASS>, java.io.Serializable { +#else +public interface SORTED_PAIR <K extends Comparable<K>> extends PAIR <K, K>, it.unimi.dsi.fastutil.SortedPair<K>, java.io.Serializable { +#endif + + /** Returns a new type-specific immutable {@link it.unimi.dsi.fastutil.SortedPair SortedPair} with given left and right value. + * + * <p>Note that if {@code left} and {@code right} are in the wrong order, they will be exchanged. + * + * @param left the left value. + * @param right the right value. + * + * @implNote This factory method delegates to the factory method of the corresponding immutable implementation. + */ +#if KEYS_PRIMITIVE + public static SORTED_PAIR of(final KEY_GENERIC_TYPE left, final KEY_GENERIC_TYPE right) { + return IMMUTABLE_SORTED_PAIR.of(left, right); +#else + public static <K extends Comparable<K>> SORTED_PAIR <K> of(final KEY_GENERIC_TYPE left, final KEY_GENERIC_TYPE right) { + return IMMUTABLE_SORTED_PAIR.of(left, right); +#endif + } +} \ No newline at end of file diff --git a/gencsource.sh b/gencsource.sh index 858e2967da33d8341c6ae2fb7116f4586168b47b..d8204c997027737939eb83dde7c081ece96645c5 100755 --- a/gencsource.sh +++ b/gencsource.sh @@ -56,14 +56,17 @@ KEY_TYPE_CAP=${class:0:$keylen} VALUE_TYPE_CAP=Object # Just for filling holes if [[ "${rem:0:1}" == "2" ]]; then - isFunction=true rem=${rem:1} rem2=${rem##[A-Z]+([a-z])} valuelen=$(( ${#rem} - ${#rem2} )) VALUE_TYPE_CAP=${rem:0:$valuelen} root=$rem2 -else - isFunction=false +fi + +if [[ "$class" == *Pair ]]; then + rem2=${rem##[A-Z]+([a-z])} + valuelen=$(( ${#rem} - ${#rem2} )) + VALUE_TYPE_CAP=${rem:0:$valuelen} fi for((k=0; k<${#TYPE_CAP[*]}; k++)); do @@ -340,6 +343,16 @@ fi)\ "#define FUNCTION ${TYPE_CAP[$k]}2${TYPE_CAP[$v]}Function\n"\ "#define MAP ${TYPE_CAP[$k]}2${TYPE_CAP[$v]}Map\n"\ "#define SORTED_MAP ${TYPE_CAP[$k]}2${TYPE_CAP[$v]}SortedMap\n"\ +"#if KEY_CLASS_Object && VALUE_CLASS_Object\n"\ +"#define PAIR it.unimi.dsi.fastutil.Pair\n"\ +"#define SORTED_PAIR it.unimi.dsi.fastutil.SortedPair\n"\ +"#else\n"\ +"#define PAIR ${TYPE_CAP[$k]}${TYPE_CAP[$v]}Pair\n"\ +"#define SORTED_PAIR ${TYPE_CAP[$k]}${TYPE_CAP[$v]}SortedPair\n"\ +"#endif\n"\ +"#define MUTABLE_PAIR ${TYPE_CAP[$k]}${TYPE_CAP[$v]}MutablePair\n"\ +"#define IMMUTABLE_PAIR ${TYPE_CAP[$k]}${TYPE_CAP[$v]}ImmutablePair\n"\ +"#define IMMUTABLE_SORTED_PAIR ${TYPE_CAP[$k]}${TYPE_CAP[$k]}ImmutableSortedPair\n"\ "#if KEYS_REFERENCE\n"\ "#define STD_SORTED_MAP SortedMap\n"\ "#define STRATEGY Strategy\n"\ @@ -362,6 +375,7 @@ fi)\ "#define KEY_LIST_ITERATOR ${TYPE_CAP2[$k]}ListIterator\n"\ "#define KEY_BIG_LIST_ITERATOR ${TYPE_CAP2[$k]}BigListIterator\n"\ "#define STD_KEY_ITERATOR ${TYPE_STD[$k]}Iterator\n"\ +"#define STD_KEY_ITERABLE ${TYPE_STD[$k]}Iterable\n"\ "#define KEY_COMPARATOR ${TYPE_STD[$k]}Comparator\n"\ \ \ @@ -514,6 +528,9 @@ fi)\ "#define FIRST_KEY first${TYPE_STD[$k]}Key\n"\ "#define LAST_KEY last${TYPE_STD[$k]}Key\n"\ "#define GET_KEY get${TYPE_STD[$k]}\n"\ +"#define PAIR_LEFT left${TYPE_STD[$k]}\n"\ +"#define PAIR_FIRST first${TYPE_STD[$k]}\n"\ +"#define PAIR_KEY key${TYPE_STD[$k]}\n"\ "#define REMOVE_KEY remove${TYPE_STD[$k]}\n"\ "#define READ_KEY read${TYPE_CAP2[$k]}\n"\ "#define WRITE_KEY write${TYPE_CAP2[$k]}\n"\ @@ -549,6 +566,9 @@ fi)\ "#define ENTRY_GET_VALUE get${TYPE_STD[$v]}Value\n"\ "#define REMOVE_FIRST_VALUE removeFirst${TYPE_STD[$v]}\n"\ "#define REMOVE_LAST_VALUE removeLast${TYPE_STD[$v]}\n"\ +"#define PAIR_RIGHT right${TYPE_STD[$v]}\n"\ +"#define PAIR_SECOND second${TYPE_STD[$v]}\n"\ +"#define PAIR_VALUE value${TYPE_STD[$v]}\n"\ \ \ "/* Methods (keys/values) */\n"\ diff --git a/makefile b/makefile index ee58f7493f74673ea6e58a16735e6ab482bba207..e22f9580354353d051f5d598fe1c5ed68f1c2236 100644 --- a/makefile +++ b/makefile @@ -86,15 +86,15 @@ source: pom fastutil-$(version)/LICENSE-2.0 \ fastutil-$(version)/makefile \ $(foreach f, $(SOURCES), fastutil-$(version)/$(f)) \ - fastutil-$(version)/$(SOURCEDIR)/{boolean,byte,char,short,int,long,float,double,object}s/package.html \ - fastutil-$(version)/$(SOURCEDIR)/io/package.html \ + fastutil-$(version)/$(SOURCEDIR)/{boolean,byte,char,short,int,long,float,double,object}s/package-info.java \ + fastutil-$(version)/$(SOURCEDIR)/io/package-info.java \ fastutil-$(version)/src/overview.html \ $$(find fastutil-$(version)/test -iname \*.java) rm fastutil-$(version) binary: make -s clean sources format - ant clean osgi javadoc + ant clean osgi jar javadoc -rm -f fastutil-$(version) ln -s . fastutil-$(version) cp dist/lib/fastutil-$(version).jar . @@ -112,7 +112,7 @@ pom: (sed -e s/VERSION/$$(grep version build.properties | cut -d= -f2)/ <pom-model.xml >pom.xml) format: - $(ECLIPSE) -nosplash -application org.eclipse.jdt.core.JavaCodeFormatter -verbose -config $(CURDIR)/.settings/org.eclipse.jdt.core.prefs $(CURDIR)/src/it/unimi/dsi/fastutil/{booleans,bytes,shorts,chars,ints,floats,longs,doubles,objects} + $(ECLIPSE) -data workspace -nosplash -application org.eclipse.jdt.core.JavaCodeFormatter -verbose -config $(CURDIR)/.settings/org.eclipse.jdt.core.prefs $(CURDIR)/src/it/unimi/dsi/fastutil/{booleans,bytes,shorts,chars,ints,floats,longs,doubles,objects} stage: pom (unset LOCAL_IVY_SETTINGS; ant stage) @@ -226,6 +226,17 @@ $(BIG_LIST_ITERATORS): drv/BigListIterator.drv; ./gencsource.sh $< $@ >$@ CSOURCES += $(BIG_LIST_ITERATORS) +PAIRS := $(foreach k,$(TYPE), $(foreach v,$(TYPE), $(GEN_SRCDIR)/$(PKG_PATH)/$(PACKAGE_$(k))/$(k)$(v)Pair.c)) +$(PAIRS): drv/Pair.drv; ./gencsource.sh $< $@ >$@ + +CSOURCES += $(PAIRS) + +SORTED_PAIRS := $(foreach k,$(TYPE_NOBOOL_NOOBJ), $(GEN_SRCDIR)/$(PKG_PATH)/$(PACKAGE_$(k))/$(k)$(k)SortedPair.c) +$(SORTED_PAIRS): drv/SortedPair.drv; ./gencsource.sh $< $@ >$@ + +CSOURCES += $(SORTED_PAIRS) + + # # Abstract implementations # @@ -439,6 +450,21 @@ $(ARRAY_INDIRECT_PRIORITY_QUEUES): drv/ArrayIndirectPriorityQueue.drv; ./gencsou CSOURCES += $(ARRAY_INDIRECT_PRIORITY_QUEUES) +MUTABLE_PAIRS := $(foreach k,$(TYPE), $(foreach v,$(TYPE), $(GEN_SRCDIR)/$(PKG_PATH)/$(PACKAGE_$(k))/$(k)$(v)MutablePair.c)) +$(MUTABLE_PAIRS): drv/MutablePair.drv; ./gencsource.sh $< $@ >$@ + +CSOURCES += $(MUTABLE_PAIRS) + +IMMUTABLE_PAIRS := $(foreach k,$(TYPE), $(foreach v,$(TYPE), $(GEN_SRCDIR)/$(PKG_PATH)/$(PACKAGE_$(k))/$(k)$(v)ImmutablePair.c)) +$(IMMUTABLE_PAIRS): drv/ImmutablePair.drv; ./gencsource.sh $< $@ >$@ + +CSOURCES += $(IMMUTABLE_PAIRS) + +IMMUTABLE_SORTED_PAIRS := $(foreach k,$(TYPE_NOBOOL_NOREF), $(GEN_SRCDIR)/$(PKG_PATH)/$(PACKAGE_$(k))/$(k)$(k)ImmutableSortedPair.c) +$(IMMUTABLE_SORTED_PAIRS): drv/ImmutableSortedPair.drv; ./gencsource.sh $< $@ >$@ + +CSOURCES += $(IMMUTABLE_SORTED_PAIRS) + # # Static containers @@ -602,6 +628,8 @@ SOURCES = \ $(SOURCEDIR)/BigList.java \ $(SOURCEDIR)/BigListIterator.java \ $(SOURCEDIR)/PriorityQueue.java \ + $(SOURCEDIR)/Pair.java \ + $(SOURCEDIR)/SortedPair.java \ $(SOURCEDIR)/IndirectPriorityQueue.java \ $(SOURCEDIR)/Arrays.java \ $(SOURCEDIR)/Swapper.java \ @@ -637,12 +665,13 @@ clean: -@find build -name \*.class -exec rm {} \; -@find . -name \*.java~ -exec rm {} \; -@find . -name \*.html~ -exec rm {} \; - -@rm -f $(foreach k, $(sort $(TYPE)), $(GEN_SRCDIR)/$(PKG_PATH)/$(PACKAGE_$(k))/*.java) + -@$(foreach k, $(sort $(TYPE)), find $(GEN_SRCDIR)/$(PKG_PATH)/$(PACKAGE_$(k)) -iname \*.java -and -not -iname \*-info.java -delete &&) true -@rm -f $(GEN_SRCDIR)/$(PKG_PATH)/io/*IO.java -@rm -f $(GEN_SRCDIR)/$(PKG_PATH)/BigArrays.java -@rm -f $(GEN_SRCDIR)/$(PKG_PATH)/*.[chj] $(GEN_SRCDIR)/$(PKG_PATH)/*/*.[chj] -@rm -fr $(DOCSDIR)/* sources: $(JSOURCES) + rm $(GEN_SRCDIR)/it/unimi/dsi/fastutil/objects/ObjectObjectPair.java csources: $(CSOURCES) diff --git a/pom.xml b/pom.xml index e21fffd3263e9007a0789841de886139bfcea49f..f1d074d270dc7ad550bbfd9cd33fdc4de7c42f4e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,8 +4,8 @@ <artifactId>fastutil</artifactId> <packaging>jar</packaging> <name>fastutil</name> - <version>8.4.3</version> - <description>fastutil extends the Java Collections Framework by providing type-specific maps, sets, lists and priority queues with a small memory footprint and fast access and insertion; provides also big (64-bit) arrays, sets and lists, and fast, practical I/O classes for binary and text files.</description> + <version>8.4.4</version> + <description>fastutil extends the Java Collections Framework by providing type-specific maps, sets, lists and priority queues with a small memory footprint and fast access and insertion; provides also big (64-bit) arrays, sets and lists, sorting algorithms, and fast, practical I/O classes for binary and text files.</description> <url>http://fastutil.di.unimi.it/</url> <licenses> <license> @@ -22,7 +22,7 @@ <developer> <id>vigna</id> <name>Sebastiano Vigna</name> - <email>vigna@di.unimi.it</email> + <email>sebastiano.vigna@unimi.it</email> </developer> </developers> <properties> diff --git a/src/it/unimi/dsi/fastutil/Pair.java b/src/it/unimi/dsi/fastutil/Pair.java new file mode 100644 index 0000000000000000000000000000000000000000..64a24befc3e59c63acb5ffc91a2e17047afaf65c --- /dev/null +++ b/src/it/unimi/dsi/fastutil/Pair.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2002-2020 Sebastiano Vigna + * + * 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 it.unimi.dsi.fastutil; + +import it.unimi.dsi.fastutil.objects.ObjectObjectImmutablePair; + +/** + * A pair of elements. + * + * <p> + * This inferface gives access to a pair of elements <<var>l</var>, <var>r</var>>, where + * <var>l</var> is the {@linkplain #left() <em>left element</em>} and <var>r</var> is the + * {@linkplain #right() <em>right element</em>}. Mutability is optional. + * + * <p> + * Since pairs have many different interpretation depending on the context, this interface offers + * alternative but equivalent access methods based on {@linkplain #first() + * first}/{@linkplain #second() second} and {@linkplain #key() key}/{@linkplain #value() value}. All + * such methods have default implementations that delegates to the standard methods. Implementations + * need only to provide {@link #left()} and {@link #right()}, and possibly {@link #left(Object)} and + * {@link #right(Object)} for mutability. + * + * <p> + * Setters return the instance, and are thus chainable. You can write + * + * <pre> + * pair.left(0).right(1) + * </pre> + * + * and, if necessary, pass this value to a method. + * + * @param <L> the type of the left element. + * @param <R> the type of the right element. + */ + +public interface Pair<L, R> { + + /** + * Returns the left element of this pair. + * + * @return the left element of this pair. + */ + public L left(); + + /** + * Returns the right element of this pair. + * + * @return the right element of this pair. + */ + public R right(); + + /** + * Sets the left element of this pair (optional operation). + * + * @param l a new value for the left element. + * + * @implNote This implementation throws an {@link UnsupportedOperationException}. + */ + public default Pair<L, R> left(final L l) { + throw new UnsupportedOperationException(); + } + + /** + * Sets the right element of this pair (optional operation). + * + * @param r a new value for the right element. + * + * @implNote This implementation throws an {@link UnsupportedOperationException}. + */ + public default Pair<L, R> right(final R r) { + throw new UnsupportedOperationException(); + } + + /** + * Returns the left element of this pair. + * + * @return the left element of this pair. + * + * @implNote This implementation delegates to {@link #left()}. + * + */ + public default L first() { + return left(); + } + + /** + * Returns the right element of this pair. + * + * @return the right element of this pair. + * + * @implNote This implementation delegates to {@link #right()}. + * + */ + public default R second() { + return right(); + } + + /** + * Sets the left element of this pair (optional operation). + * + * @param l a new value for the left element. + * + * @implNote This implementation delegates to {@link #left(Object)}. + */ + public default Pair<L, R> first(final L l) { + return left(l); + } + + /** + * Sets the right element of this pair (optional operation). + * + * @param r a new value for the right element. + * + * @implNote This implementation delegates to {@link #right(Object)}. + */ + public default Pair<L, R> second(final R r) { + return right(r); + } + + /** + * Sets the left element of this pair (optional operation). + * + * @param l a new value for the left element. + * + * @implNote This implementation delegates to {@link #left(Object)}. + */ + public default Pair<L, R> key(final L l) { + return left(l); + } + + /** + * Sets the right element of this pair (optional operation). + * + * @param r a new value for the right element. + * + * @implNote This implementation delegates to {@link #right(Object)}. + */ + public default Pair<L, R> value(final R r) { + return right(r); + } + + /** + * Returns the left element of this pair. + * + * @return the left element of this pair. + * + * @implNote This implementation delegates to {@link #left()}. + * + */ + public default L key() { + return left(); + } + + /** + * Returns the right element of this pair. + * + * @return the right element of this pair. + * + * @implNote This implementation delegates to {@link #right()}. + * + */ + public default R value() { + return right(); + } + + /** + * Returns a new immutable {@link it.unimi.dsi.fastutil.Pair Pair} with given left and right + * value. + * + * @param l the left value. + * @param r the right value. + * + * @implNote This factory method returns an instance of {@link ObjectObjectImmutablePair}. + */ + public static <L, R> Pair<L, R> of(final L l, final R r) { + return new ObjectObjectImmutablePair<>(l, r); + } +} diff --git a/src/it/unimi/dsi/fastutil/SortedPair.java b/src/it/unimi/dsi/fastutil/SortedPair.java new file mode 100644 index 0000000000000000000000000000000000000000..670a3154d13b07db2c551a6c2b2b8be0980c9bf0 --- /dev/null +++ b/src/it/unimi/dsi/fastutil/SortedPair.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2002-2020 Sebastiano Vigna + * + * 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 it.unimi.dsi.fastutil; + +import it.unimi.dsi.fastutil.objects.ObjectObjectImmutablePair; +import it.unimi.dsi.fastutil.objects.ObjectObjectImmutableSortedPair; + +/** + * A pair of sorted elements. + * + * <p> + * This interface strengthen {@link Pair}, without adding methods. It assumes that both elements of + * the pair are of the same type, and that they are primitive or comparable. It guarantees that the + * {@linkplain #left() left element} is smaller than or equal to the {@linkplain #right() right + * element}. + * + * <p> + * Implementations of this class can be used to represent <em>unordered pairs</em> by + * canonicalization. Note that, in particular, if you build a sorted pair using a left and right + * element in the wrong order they will be exchanged. + * + * @param <K> the type of the elements. + */ + +public interface SortedPair<K extends Comparable<K>> extends Pair<K, K> { + + /** + * Returns a new immutable {@link it.unimi.dsi.fastutil.SortedPair SortedPair} with given left + * and right value. + * + * <p> + * Note that if {@code left} and {@code right} are in the wrong order, they will be exchanged. + * + * @param l the left value. + * @param r the right value. + * + * @implNote This factory method delegates to + * {@link ObjectObjectImmutablePair#of(Object, Object)}. + */ + public static <K extends Comparable<K>> SortedPair<K> of(final K l, final K r) { + return ObjectObjectImmutableSortedPair.of(l, r); + } +} diff --git a/src/it/unimi/dsi/fastutil/booleans/package-info.java b/src/it/unimi/dsi/fastutil/booleans/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..372055bd36fc4d2591d694285991f8a51d7bdb3c --- /dev/null +++ b/src/it/unimi/dsi/fastutil/booleans/package-info.java @@ -0,0 +1,11 @@ +/** + * Type-specific classes for boolean elements or keys. + * + * <p> + * Not all classes are provided in a boolean-specific version: sorted sets and + * maps not generated, as they are useless. Unsorted sets and maps are kept + * around for orthogonality, whereas + * {@link it.unimi.dsi.fastutil.booleans.BooleanCollection} is used by maps with + * boolean values. + */ +package it.unimi.dsi.fastutil.booleans; \ No newline at end of file diff --git a/src/it/unimi/dsi/fastutil/booleans/package.html b/src/it/unimi/dsi/fastutil/booleans/package.html deleted file mode 100644 index 17fc00934cb713d53869b64d0ec6ec6fed5e9b0a..0000000000000000000000000000000000000000 --- a/src/it/unimi/dsi/fastutil/booleans/package.html +++ /dev/null @@ -1,15 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> - <head> - <title>fastutil</title> - </head> - - <body> - <p>Provides type-specific classes for boolean elements or keys. - - <p>Not all classes are provided in a boolean-specific version: sorted - sets and maps not generated (as they are completely - useless). Unsorted sets and maps are kept for orthogonality, whereas - {@link it.unimi.dsi.fastutil.booleans.BooleanCollection} is used by maps with boolean values. - </body> -</html> diff --git a/src/it/unimi/dsi/fastutil/bytes/package-info.java b/src/it/unimi/dsi/fastutil/bytes/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..e641d52de050779bf082820439901385f9927b63 --- /dev/null +++ b/src/it/unimi/dsi/fastutil/bytes/package-info.java @@ -0,0 +1,4 @@ +/** + * Type-specific classes for byte elements or keys. + */ +package it.unimi.dsi.fastutil.bytes; diff --git a/src/it/unimi/dsi/fastutil/bytes/package.html b/src/it/unimi/dsi/fastutil/bytes/package.html deleted file mode 100644 index e50134e6a9e495a0899c0b6a4fe7e8020a9ea8ad..0000000000000000000000000000000000000000 --- a/src/it/unimi/dsi/fastutil/bytes/package.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> - <head> - <title>fastutil</title> - </head> - - <body> - <p>Provides type-specific classes for byte elements or keys. - </body> -</html> diff --git a/src/it/unimi/dsi/fastutil/chars/package-info.java b/src/it/unimi/dsi/fastutil/chars/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..e2cf56e3e58f4d87e87bb8b1de1fa30c7a1e4409 --- /dev/null +++ b/src/it/unimi/dsi/fastutil/chars/package-info.java @@ -0,0 +1,4 @@ +/** + * Type-specific classes for character elements or keys. + */ +package it.unimi.dsi.fastutil.chars; diff --git a/src/it/unimi/dsi/fastutil/chars/package.html b/src/it/unimi/dsi/fastutil/chars/package.html deleted file mode 100644 index 32f5ba606f79ebef41a1ccc602955b820937b39a..0000000000000000000000000000000000000000 --- a/src/it/unimi/dsi/fastutil/chars/package.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> - <head> - <title>fastutil</title> - </head> - - <body> - <p>Provides type-specific classes for character elements or keys. - </body> -</html> diff --git a/src/it/unimi/dsi/fastutil/doubles/package-info.java b/src/it/unimi/dsi/fastutil/doubles/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..845fb702703c840aafed7a2929cb1ff73f0b35ac --- /dev/null +++ b/src/it/unimi/dsi/fastutil/doubles/package-info.java @@ -0,0 +1,4 @@ +/** + * Type-specific classes for double elements or keys. + */ +package it.unimi.dsi.fastutil.doubles; diff --git a/src/it/unimi/dsi/fastutil/doubles/package.html b/src/it/unimi/dsi/fastutil/doubles/package.html deleted file mode 100644 index c6d723bbc758972ace22f7cd0ef0d634a039be98..0000000000000000000000000000000000000000 --- a/src/it/unimi/dsi/fastutil/doubles/package.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> - <head> - <title>fastutil</title> - </head> - - <body> - <p>Provides type-specific classes for double elements or keys. - </body> -</html> diff --git a/src/it/unimi/dsi/fastutil/floats/package-info.java b/src/it/unimi/dsi/fastutil/floats/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..ca58e9531b3fa814a36d7319b17a1d58b97186fd --- /dev/null +++ b/src/it/unimi/dsi/fastutil/floats/package-info.java @@ -0,0 +1,4 @@ +/** + * Type-specific classes for float elements or keys. + */ +package it.unimi.dsi.fastutil.floats; diff --git a/src/it/unimi/dsi/fastutil/floats/package.html b/src/it/unimi/dsi/fastutil/floats/package.html deleted file mode 100644 index 8d96d6e97b34591f880f0cf0585126624e9eb6ec..0000000000000000000000000000000000000000 --- a/src/it/unimi/dsi/fastutil/floats/package.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> - <head> - <title>fastutil</title> - </head> - - <body> - <p>Provides type-specific classes for float elements or keys. - </body> -</html> diff --git a/src/it/unimi/dsi/fastutil/ints/package-info.java b/src/it/unimi/dsi/fastutil/ints/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..e9c920fd6bfc70e2d04071b5e63795be2e7e8c5b --- /dev/null +++ b/src/it/unimi/dsi/fastutil/ints/package-info.java @@ -0,0 +1,4 @@ +/** + * Type-specific classes for integer elements or keys. + */ +package it.unimi.dsi.fastutil.ints; diff --git a/src/it/unimi/dsi/fastutil/ints/package.html b/src/it/unimi/dsi/fastutil/ints/package.html deleted file mode 100644 index de84c2d02d9ecd05fd26ea6fd28f576d0f4e21a4..0000000000000000000000000000000000000000 --- a/src/it/unimi/dsi/fastutil/ints/package.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> - <head> - <title>fastutil</title> - </head> - - <body> - <p>Provides type-specific classes for integer elements or keys. - </body> -</html> diff --git a/src/it/unimi/dsi/fastutil/io/package-info.java b/src/it/unimi/dsi/fastutil/io/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..454a0b0a921c603d83e78bbd1357e3149e854303 --- /dev/null +++ b/src/it/unimi/dsi/fastutil/io/package-info.java @@ -0,0 +1,18 @@ +/** + * Classes and static methods that make object and primitive-type I/O easier and faster. + * + * <p> + * Classes in this package provide very efficient, unsynchronized buffered + * {@linkplain it.unimi.dsi.fastutil.io.FastBufferedInputStream input} and + * {@linkplain it.unimi.dsi.fastutil.io.FastBufferedOutputStream output} streams (with support for + * {@linkplain it.unimi.dsi.fastutil.io.RepositionableStream repositioning}, too) and + * {@linkplain it.unimi.dsi.fastutil.io.FastByteArrayInputStream fast streams} based on byte arrays. + * + * <p> + * Static containers provide instead a wealth of methods that can be used to + * {@linkplain BinIO#storeObject(Object, CharSequence) serialize} or + * {@linkplain BinIO#loadObject(CharSequence) deserialize} very easily objects and + * {@linkplain BinIO#storeInts(int[], CharSequence) arrays}, even + * {@linkplain TextIO#storeInts(int[], CharSequence) in text form}. + */ +package it.unimi.dsi.fastutil.io; diff --git a/src/it/unimi/dsi/fastutil/io/package.html b/src/it/unimi/dsi/fastutil/io/package.html deleted file mode 100644 index 99be11c5cb1497145d67a3c4e7a1e3c8bd8a9ca0..0000000000000000000000000000000000000000 --- a/src/it/unimi/dsi/fastutil/io/package.html +++ /dev/null @@ -1,19 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> - <head> - <title>fastutil</title> - </head> - - <body> - - <p>Provides classes and static methods that make object and primitive-type I/O easier and faster. - - - <h2>PackageSpecificaton</h2> - <p>Classes in this package provide very efficient, unsynchronised buffered - input and output stream (with support for repositioning, too) and fast streams - based on byte arrays. Static containers - provide instead a wealth of methods that can be used to serialize/deserialize - very easily objects and arrays. - </body> -</html> diff --git a/src/it/unimi/dsi/fastutil/longs/package-info.java b/src/it/unimi/dsi/fastutil/longs/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..299b13aa2206fecfe3d0e8f266515020f36e0813 --- /dev/null +++ b/src/it/unimi/dsi/fastutil/longs/package-info.java @@ -0,0 +1,4 @@ +/** + * Type-specific classes for long elements or keys. + */ +package it.unimi.dsi.fastutil.longs; diff --git a/src/it/unimi/dsi/fastutil/longs/package.html b/src/it/unimi/dsi/fastutil/longs/package.html deleted file mode 100644 index efdcf6886e844d1403f8e1d483abf7bcc383f7c5..0000000000000000000000000000000000000000 --- a/src/it/unimi/dsi/fastutil/longs/package.html +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> - <head> - <title>fastutil</title> - </head> - - <body> - - <p>Provides type-specific classes for long elements or keys. - - </body> -</html> diff --git a/src/it/unimi/dsi/fastutil/objects/package-info.java b/src/it/unimi/dsi/fastutil/objects/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..47a4f4754b7bab962caf7530a28d31d795c74869 --- /dev/null +++ b/src/it/unimi/dsi/fastutil/objects/package-info.java @@ -0,0 +1,11 @@ +/** + * Type-specific classes for object elements or keys. + * + * <p> + * Whenever possible and useful, {@code fastutil} provides both typical + * collections, which compare objects using {@code equals()}, and + * {@linkplain it.unimi.dsi.fastutil.objects.ReferenceSet + * <em>reference-based</em> collections}, which use identity ({@code ==}). See + * the related comments in the overview. + */ +package it.unimi.dsi.fastutil.objects; diff --git a/src/it/unimi/dsi/fastutil/objects/package.html b/src/it/unimi/dsi/fastutil/objects/package.html deleted file mode 100644 index d98003ded02fb9691dc45450a6586a20edceb2f9..0000000000000000000000000000000000000000 --- a/src/it/unimi/dsi/fastutil/objects/package.html +++ /dev/null @@ -1,19 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> - <head> - <title>fastutil</title> - </head> - - <body> - - <p>Provides type-specific classes for object elements or keys. - - <p>Whenever possible, {@code fastutil} provides both typical - collections, which compare objects using {@code equals()}, and - <em>reference-based</em> collections, which use equality - ({@code ==}). See the related comments in the overview. - - <p>Of course, reference-based sorted sets and maps make no -sense, and are not generated. - </body> -</html> diff --git a/src/it/unimi/dsi/fastutil/shorts/package-info.java b/src/it/unimi/dsi/fastutil/shorts/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..f6473e5a7c779402b7d43fafd0946c19b2c772b1 --- /dev/null +++ b/src/it/unimi/dsi/fastutil/shorts/package-info.java @@ -0,0 +1,4 @@ +/** + * Type-specific classes for short elements or keys. + */ +package it.unimi.dsi.fastutil.shorts; diff --git a/src/it/unimi/dsi/fastutil/shorts/package.html b/src/it/unimi/dsi/fastutil/shorts/package.html deleted file mode 100644 index 5630b585d83d014e0c1ed53fcd9672a912c6906b..0000000000000000000000000000000000000000 --- a/src/it/unimi/dsi/fastutil/shorts/package.html +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> - <head> - <title>fastutil</title> - </head> - - <body> - - <p>Provides type-specific classes for short elements or keys. - - </body> -</html> diff --git a/src/overview.html b/src/overview.html index 5e33e5cc3cd85ef0b69220f06b6717a47da33f79..ac71b9a4450bf16f71ca8348cba0d74cee001f92 100644 --- a/src/overview.html +++ b/src/overview.html @@ -457,7 +457,7 @@ <li>The standard entry-set iterators for hash-based maps use an entry object that refers to the data contained in the hash table. If you retrieve an entry and delete it, the entry object will become invalid and will throw - an {@link java.util.ArrayIndexOutOfBoundsException} exception. This does not + an {@link java.lang.ArrayIndexOutOfBoundsException} exception. This does not apply to fast iterators (see above).</li> <li>A name clash between the list and collection interfaces diff --git a/test/it/unimi/dsi/fastutil/ints/Int2IntMapGenericTest.java b/test/it/unimi/dsi/fastutil/ints/Int2IntMapGenericTest.java index 67440c173d8e9f695454ac924e9ea90e3e539e62..e74485a56de089132b5d93f5b293a8c5cc58c593 100644 --- a/test/it/unimi/dsi/fastutil/ints/Int2IntMapGenericTest.java +++ b/test/it/unimi/dsi/fastutil/ints/Int2IntMapGenericTest.java @@ -45,6 +45,7 @@ import java.util.function.IntSupplier; import java.util.function.Supplier; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -56,6 +57,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectIterator; import it.unimi.dsi.fastutil.objects.ObjectSet; +@Ignore @RunWith(Parameterized.class) @SuppressWarnings("deprecation") public abstract class Int2IntMapGenericTest<M extends Int2IntMap> { diff --git a/test/it/unimi/dsi/fastutil/ints/Int2ObjectMapGenericTest.java b/test/it/unimi/dsi/fastutil/ints/Int2ObjectMapGenericTest.java index e4c039667fbb0bfce839aa8da98f42419ce9ff47..17f92bac23aceef25201b55fb945ddafc065364f 100644 --- a/test/it/unimi/dsi/fastutil/ints/Int2ObjectMapGenericTest.java +++ b/test/it/unimi/dsi/fastutil/ints/Int2ObjectMapGenericTest.java @@ -46,6 +46,7 @@ import java.util.function.IntSupplier; import java.util.function.Supplier; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -58,6 +59,7 @@ import it.unimi.dsi.fastutil.objects.ObjectIterator; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ObjectSet; +@Ignore @SuppressWarnings("deprecation") @RunWith(Parameterized.class) public abstract class Int2ObjectMapGenericTest<M extends Int2ObjectMap<Integer>> { diff --git a/test/it/unimi/dsi/fastutil/ints/IntArrayListTest.java b/test/it/unimi/dsi/fastutil/ints/IntArrayListTest.java index b836c9d93686ca55782d4a642282ef84718d47d1..c47e298a4259c6e0ed2a9190107689f7a246bb96 100644 --- a/test/it/unimi/dsi/fastutil/ints/IntArrayListTest.java +++ b/test/it/unimi/dsi/fastutil/ints/IntArrayListTest.java @@ -50,6 +50,26 @@ public class IntArrayListTest { assertEquals(IntArrayList.wrap(new int[] { 42, 24 }), list); } + @Test + public void testAddAll() { + final IntArrayList l = IntArrayList.wrap(new int[] { 0, 1 }); + l.addAll(IntArrayList.wrap(new int[] { 2, 3 } )); + assertEquals(IntArrayList.wrap(new int[] { 0, 1, 2, 3 }), l); + // Test object based lists still work too. + l.addAll(java.util.Arrays.asList(Integer.valueOf(4), Integer.valueOf(5))); + assertEquals(IntArrayList.wrap(new int[] { 0, 1, 2, 3, 4, 5 }), l); + } + + @Test + public void testAddAllAtIndex() { + final IntArrayList l = IntArrayList.wrap(new int[] { 0, 3 }); + l.addAll(1, IntArrayList.wrap(new int[] { 1, 2 } )); + assertEquals(IntArrayList.wrap(new int[] { 0, 1, 2, 3 }), l); + // Test object based lists still work too. + l.addAll(2, java.util.Arrays.asList(Integer.valueOf(4), Integer.valueOf(5))); + assertEquals(IntArrayList.wrap(new int[] { 0, 1, 4, 5, 2, 3 }), l); + } + @Test public void testRemoveAll() { IntArrayList l = IntArrayList.wrap(new int[] { 0, 1, 1, 2 }); @@ -63,7 +83,7 @@ public class IntArrayListTest { @Test public void testSort() { - IntArrayList l = IntArrayList.wrap(new int[] { 4, 2, 1, 3 }); + final IntArrayList l = IntArrayList.wrap(new int[] { 4, 2, 1, 3 }); l.sort(null); assertEquals(IntArrayList.wrap(new int[] { 1, 2, 3, 4 }), l); } @@ -128,4 +148,9 @@ public class IntArrayListTest { l.size(100); } + @Test + public void testOf() { + final IntArrayList l = IntArrayList.of(0, 1, 2); + assertEquals(IntArrayList.wrap(new int[] { 0, 1, 2 }), l); + } } diff --git a/test/it/unimi/dsi/fastutil/ints/IntBigArrayBigListTest.java b/test/it/unimi/dsi/fastutil/ints/IntBigArrayBigListTest.java index 6dd2dfff4784cabfc3d274372dcc93eb1f70a9ad..512e716ae11d3c6195b49827fed5ad5ecd76faf4 100644 --- a/test/it/unimi/dsi/fastutil/ints/IntBigArrayBigListTest.java +++ b/test/it/unimi/dsi/fastutil/ints/IntBigArrayBigListTest.java @@ -614,4 +614,10 @@ public class IntBigArrayBigListTest { final IntBigArrayBigList l = new IntBigArrayBigList(); l.size(100); } + + @Test + public void testOf() { + final IntBigArrayBigList l = IntBigArrayBigList.of(0, 1, 2); + assertEquals(IntBigArrayBigList.wrap(BigArrays.wrap(new int[] { 0, 1, 2 })), l); + } } diff --git a/test/it/unimi/dsi/fastutil/ints/IntOpenHashSetTest.java b/test/it/unimi/dsi/fastutil/ints/IntOpenHashSetTest.java index 7cb8862b6c511e550b5f876c5ba7dd6ede484edd..f14b4aa5e49f7840b238ccbeb1379f336bb72181 100644 --- a/test/it/unimi/dsi/fastutil/ints/IntOpenHashSetTest.java +++ b/test/it/unimi/dsi/fastutil/ints/IntOpenHashSetTest.java @@ -58,6 +58,26 @@ public class IntOpenHashSetTest { assertFalse(s.equals(new ObjectOpenHashSet<>(new Integer[] { 1, null }))); } + @Test + public void testEqualsSameType() { + final IntOpenHashSet s = new IntOpenHashSet(new int[] { 1, 2, 3 }); + assertTrue(s.equals(new IntOpenHashSet(new int[] { 1, 2, 3 }))); + } + + @SuppressWarnings("unlikely-arg-type") + @Test + public void testEqualsIntSetType() { + final IntOpenHashSet s = new IntOpenHashSet(new int[] { 1, 2, 3 }); + assertTrue(s.equals(new IntArraySet(new int[] { 1, 2, 3 }))); + } + + @SuppressWarnings({ "boxing", "unlikely-arg-type" }) + @Test + public void testEqualsObjectSet() { + final IntOpenHashSet s = new IntOpenHashSet(new int[] { 1, 2, 3 }); + assertTrue(s.equals(new ObjectOpenHashSet<>(new Integer[] { 1, 2, 3 }))); + } + @Test public void testInfiniteLoop1() { final IntOpenHashSet set = new IntOpenHashSet(); @@ -280,6 +300,11 @@ public class IntOpenHashSetTest { assertEquals(8, s.n); } + @Test + public void testOf() { + final IntOpenHashSet s = IntOpenHashSet.of(0, 1, 2); + assertEquals(new IntOpenHashSet(new int[] { 0, 1, 2 }), s); + } @SuppressWarnings("boxing") private static void checkTable(final IntOpenHashSet s) { @@ -348,8 +373,7 @@ public class IntOpenHashSetTest { /* Now we check that m actually holds that data. */ - for (final java.util.Iterator i = t.iterator(); i.hasNext();) { - final Object e = i.next(); + for (final Object e : t) { assertTrue("Error: m and t differ on a key (" + e + ") after insertion (iterating on t)", m.contains(e)); } @@ -398,8 +422,7 @@ public class IntOpenHashSetTest { assertTrue("Error: !t.equals(m) after removal", t.equals(m)); /* Now we check that m actually holds that data. */ - for (final java.util.Iterator i = t.iterator(); i.hasNext();) { - final Object e = i.next(); + for (final Object e : t) { assertFalse("Error: m and t differ on a key (" + e + ") after removal (iterating on t)", !m.contains(e)); } diff --git a/test/it/unimi/dsi/fastutil/ints/StripedInt2IntOpenHashMapTest.java b/test/it/unimi/dsi/fastutil/ints/StripedInt2IntOpenHashMapTest.java index f12b948f32b750a636df9408c47657cbcb087c7d..924579140f5cb864ae120d79be4f38d62f0a517b 100644 --- a/test/it/unimi/dsi/fastutil/ints/StripedInt2IntOpenHashMapTest.java +++ b/test/it/unimi/dsi/fastutil/ints/StripedInt2IntOpenHashMapTest.java @@ -1,5 +1,7 @@ package it.unimi.dsi.fastutil.ints; +import org.junit.Ignore; + /* * Copyright (C) 2017-2020 Sebastiano Vigna * @@ -17,6 +19,7 @@ package it.unimi.dsi.fastutil.ints; */ +@Ignore public class StripedInt2IntOpenHashMapTest { // // diff --git a/test/it/unimi/dsi/fastutil/objects/ObjectOpenHashSetTest.java b/test/it/unimi/dsi/fastutil/objects/ObjectOpenHashSetTest.java index 8babef527c3258ae7567d76cf745b1754824f9c8..bea4940738fb34dc7ac4264a2db64188a7a5f75d 100644 --- a/test/it/unimi/dsi/fastutil/objects/ObjectOpenHashSetTest.java +++ b/test/it/unimi/dsi/fastutil/objects/ObjectOpenHashSetTest.java @@ -26,6 +26,7 @@ import org.junit.Ignore; import org.junit.Test; import it.unimi.dsi.fastutil.Hash; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; @SuppressWarnings("rawtypes") public class ObjectOpenHashSetTest { @@ -35,7 +36,7 @@ public class ObjectOpenHashSetTest { @SuppressWarnings("boxing") public void testStrangeRetainAllCase() { - ObjectArrayList<Integer> initialElements = ObjectArrayList.wrap(new Integer[] { 586, 940, + final ObjectArrayList<Integer> initialElements = ObjectArrayList.wrap(new Integer[] { 586, 940, 1086, 1110, 1168, 1184, 1185, 1191, 1196, 1229, 1237, 1241, 1277, 1282, 1284, 1299, 1308, 1309, 1310, 1314, 1328, 1360, 1366, 1370, 1378, 1388, 1392, 1402, 1406, 1411, 1426, 1437, @@ -57,11 +58,11 @@ public class ObjectOpenHashSetTest { 7094, 7379, 7384, 7388, 7394, 7414, 7419, 7458, 7459, 7466, 7467 }); - ObjectArrayList<Integer> retainElements = ObjectArrayList.wrap(new Integer[] { 586 }); + final ObjectArrayList<Integer> retainElements = ObjectArrayList.wrap(new Integer[] { 586 }); // Initialize both implementations with the same data - ObjectOpenHashSet<Integer> instance = new ObjectOpenHashSet<>(initialElements); - ObjectRBTreeSet<Integer> referenceInstance = new ObjectRBTreeSet<>(initialElements); + final ObjectOpenHashSet<Integer> instance = new ObjectOpenHashSet<>(initialElements); + final ObjectRBTreeSet<Integer> referenceInstance = new ObjectRBTreeSet<>(initialElements); instance.retainAll(retainElements); referenceInstance.retainAll(retainElements); @@ -76,13 +77,19 @@ public class ObjectOpenHashSetTest { assertEquals(referenceInstance, instance); } + @Test + public void testOf() { + final ObjectOpenHashSet<Long> s = ObjectOpenHashSet.of(Long.valueOf(0), Long.valueOf(1), Long.valueOf(2)); + assertEquals(new LongOpenHashSet(new long[] { 0, 1, 2 }), s); + } + private static java.util.Random r = new java.util.Random(0); private static Object genKey() { return Integer.toBinaryString(r.nextInt()); } - private static void checkTable(ObjectOpenHashSet<Integer> s) { + private static void checkTable(final ObjectOpenHashSet<Integer> s) { final Object[] key = s.key; assert (s.n & -s.n) == s.n : "Table length is not a power of two: " + s.n; assert s.n == key.length - 1; @@ -94,13 +101,13 @@ public class ObjectOpenHashSetTest { if (s.containsNull && ! s.contains(null)) throw new AssertionError("Hash table should contain null by internal state, but it doesn't when queried"); if (! s.containsNull && s.contains(null)) throw new AssertionError("Hash table should not contain null by internal state, but it does when queried"); - java.util.HashSet<String> t = new java.util.HashSet<>(); + final java.util.HashSet<String> t = new java.util.HashSet<>(); for (int i = s.size(); i-- != 0;) if (key[i] != null && !t.add((String)key[i])) throw new AssertionError("Key " + key[i] + " appears twice"); } - private static void printProbes(ObjectOpenHashSet m) { + private static void printProbes(final ObjectOpenHashSet m) { long totProbes = 0; double totSquareProbes = 0; int maxProbes = 0; @@ -129,10 +136,10 @@ public class ObjectOpenHashSetTest { @SuppressWarnings("unchecked") - private static void test(int n, float f) { + private static void test(final int n, final float f) { int c; ObjectOpenHashSet m = new ObjectOpenHashSet(Hash.DEFAULT_INITIAL_SIZE, f); - java.util.Set t = new java.util.HashSet(); + final java.util.Set t = new java.util.HashSet(); /* First of all, we fill t with random data. */ for (int i = 0; i < f * n; i++) t.add((genKey())); @@ -143,14 +150,13 @@ public class ObjectOpenHashSetTest { printProbes(m); checkTable(m); /* Now we check that m actually holds that data. */ - for (java.util.Iterator i = t.iterator(); i.hasNext();) { - Object e = i.next(); + for (final Object e : t) { assertTrue("Error: m and t differ on a key (" + e + ") after insertion (iterating on t)", m.contains(e)); } /* Now we check that m actually holds that data, but iterating on m. */ c = 0; - for (java.util.Iterator i = m.iterator(); i.hasNext();) { - Object e = i.next(); + for (final java.util.Iterator i = m.iterator(); i.hasNext();) { + final Object e = i.next(); c++; assertTrue("Error: m and t differ on a key (" + e + ") after insertion (iterating on m)", t.contains(e)); } @@ -160,7 +166,7 @@ public class ObjectOpenHashSetTest { * use the polymorphic method. */ for (int i = 0; i < n; i++) { - Object T = genKey(); + final Object T = genKey(); assertTrue("Error: divergence in keys between t and m (polymorphic method)", m.contains(T) == t.contains((T))); } /* @@ -168,15 +174,15 @@ public class ObjectOpenHashSetTest { * m we use the standard method. */ for (int i = 0; i < n; i++) { - Object T = genKey(); + final Object T = genKey(); assertTrue("Error: divergence between t and m (standard method)", m.contains((T)) == t.contains((T))); } /* * Check that addOrGet does indeed return the original instance, not a copy */ - for (java.util.Iterator i = m.iterator(); i.hasNext();) { - Object e = i.next(); - Object e2 = m.addOrGet(new StringBuilder((String)e).toString()); // Make a new object! + for (final java.util.Iterator i = m.iterator(); i.hasNext();) { + final Object e = i.next(); + final Object e2 = m.addOrGet(new StringBuilder((String)e).toString()); // Make a new object! assertTrue("addOrGet does not return the same object", e == e2); } /* This should not have modified the table */ @@ -199,36 +205,35 @@ public class ObjectOpenHashSetTest { /* * Now we check that m actually holds that data. */ - for (java.util.Iterator i = t.iterator(); i.hasNext();) { - Object e = i.next(); + for (final Object e : t) { assertTrue("Error: m and t differ on a key (" + e + ") after removal (iterating on t)", m.contains(e)); } /* Now we check that m actually holds that data, but iterating on m. */ - for (java.util.Iterator i = m.iterator(); i.hasNext();) { - Object e = i.next(); + for (final java.util.Iterator i = m.iterator(); i.hasNext();) { + final Object e = i.next(); assertTrue("Error: m and t differ on a key (" + e + ") after removal (iterating on m)", t.contains(e)); } /* Now we make m into an array, make it again a set and check it is OK. */ - Object a[] = m.toArray(); + final Object a[] = m.toArray(); assertTrue("Error: toArray() output (or array-based constructor) is not OK", new ObjectOpenHashSet(a).equals(m)); /* Now we check cloning. */ assertTrue("Error: m does not equal m.clone()", m.equals(m.clone())); assertTrue("Error: m.clone() does not equal m", m.clone().equals(m)); - int h = m.hashCode(); + final int h = m.hashCode(); /* Now we save and read m. */ try { - java.io.File ff = new java.io.File("it.unimi.dsi.fastutil.test.junit." + m.getClass().getSimpleName() + "." + n); - java.io.OutputStream os = new java.io.FileOutputStream(ff); - java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(os); + final java.io.File ff = new java.io.File("it.unimi.dsi.fastutil.test.junit." + m.getClass().getSimpleName() + "." + n); + final java.io.OutputStream os = new java.io.FileOutputStream(ff); + final java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(os); oos.writeObject(m); oos.close(); - java.io.InputStream is = new java.io.FileInputStream(ff); - java.io.ObjectInputStream ois = new java.io.ObjectInputStream(is); + final java.io.InputStream is = new java.io.FileInputStream(ff); + final java.io.ObjectInputStream ois = new java.io.ObjectInputStream(is); m = (ObjectOpenHashSet)ois.readObject(); ois.close(); ff.delete(); } - catch (Exception e) { + catch (final Exception e) { e.printStackTrace(); System.exit(1); } @@ -236,8 +241,8 @@ public class ObjectOpenHashSetTest { checkTable(m); printProbes(m); /* Now we check that m actually holds that data, but iterating on m. */ - for (java.util.Iterator i = m.iterator(); i.hasNext();) { - Object e = i.next(); + for (final java.util.Iterator i = m.iterator(); i.hasNext();) { + final Object e = i.next(); assertTrue("Error: m and t differ on a key (" + e + ") after save/read", t.contains(e)); } /* Now we put and remove random data in m and t, checking that the result is the same. */ @@ -252,7 +257,7 @@ public class ObjectOpenHashSetTest { /* * Now we take out of m everything , and check that it is empty. */ - for (java.util.Iterator i = m.iterator(); i.hasNext();) { + for (final java.util.Iterator i = m.iterator(); i.hasNext();) { i.next(); i.remove(); } @@ -292,7 +297,7 @@ public class ObjectOpenHashSetTest { @Test public void testGet() { final ObjectOpenHashSet<String> s = new ObjectOpenHashSet<>(); - String a = "a"; + final String a = "a"; assertTrue(s.add(a)); assertSame(a, s.get("a")); assertNull(s.get("b"));