diff --git a/pom.xml b/pom.xml index 9188ff796b..de218655d1 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ org.easymock easymock - 5.3.0 + 5.4.0 test diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 9abcc6b303..2f20ba2244 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -40,14 +40,18 @@ Add CollectionUtils.duplicateList(Collection). Add CollectionUtils.duplicateSet(Collection). Add CollectionUtils.duplicateSequencedSet(Collection). + Add HashBag.HashBag(Iterable). + Add TreeBag.TreeBag(Iterable). + Add CartesianProductIterator #509. - Update bloom filter documentation #508. - Bump commons-codec:commons-codec from 1.17.0 to 1.17.1 #514. - Bump org.apache.commons:commons-lang3 from 3.14.0 to 3.17.0 #516, #525, #535. + Update bloom filter documentation #508. + Bump commons-codec:commons-codec from 1.17.0 to 1.17.1 #514. + Bump org.apache.commons:commons-lang3 from 3.14.0 to 3.17.0 #516, #525, #535. Bump org.apache.commons:commons-parent from 71 to 74 #534. Bump org.hamcrest:hamcrest from 2.2 to 3.0 #522, #532. Bump com.google.guava:guava-testlib from 33.2.1-jre to 33.3.0-jre #531. Bump MathJax from 2.7.2 to 2.7.9. + Bump org.easymock:easymock from 5.3.0 to 5.4.0 #521. diff --git a/src/main/java/org/apache/commons/collections4/CollectionUtils.java b/src/main/java/org/apache/commons/collections4/CollectionUtils.java index cf7d7c984b..ff53f36dca 100644 --- a/src/main/java/org/apache/commons/collections4/CollectionUtils.java +++ b/src/main/java/org/apache/commons/collections4/CollectionUtils.java @@ -63,50 +63,54 @@ public class CollectionUtils { */ private static class CardinalityHelper { + static boolean equals(final Collection a, final Collection b) { + return new HashBag<>(a).equals(new HashBag<>(b)); + } + /** Contains the cardinality for each object in collection A. */ - final Map cardinalityA; + final Bag cardinalityA; /** Contains the cardinality for each object in collection B. */ - final Map cardinalityB; + final Bag cardinalityB; /** - * Create a new CardinalityHelper for two collections. + * Creates a new CardinalityHelper for two collections. + * * @param a the first collection * @param b the second collection */ CardinalityHelper(final Iterable a, final Iterable b) { - cardinalityA = getCardinalityMap(a); - cardinalityB = getCardinalityMap(b); + cardinalityA = new HashBag<>(a); + cardinalityB = new HashBag<>(b); } /** - * Returns the frequency of this object in collection A. - * @param obj the object + * Gets the frequency of this object in collection A. + * + * @param key the key whose associated frequency is to be returned. * @return the frequency of the object in collection A */ - public int freqA(final Object obj) { - return getFreq(obj, cardinalityA); + public int freqA(final Object key) { + return getFreq(key, cardinalityA); } /** - * Returns the frequency of this object in collection B. - * @param obj the object + * Gets the frequency of this object in collection B. + * + * @param key the key whose associated frequency is to be returned. * @return the frequency of the object in collection B */ - public int freqB(final Object obj) { - return getFreq(obj, cardinalityB); + public int freqB(final Object key) { + return getFreq(key, cardinalityB); } - private int getFreq(final Object obj, final Map freqMap) { - final Integer count = freqMap.get(obj); - if (count != null) { - return count.intValue(); - } - return 0; + private int getFreq(final Object key, final Bag freqMap) { + return freqMap.getCount(key); } /** - * Returns the maximum frequency of an object. + * Gets the maximum frequency of an object. + * * @param obj the object * @return the maximum frequency of the object */ @@ -115,7 +119,8 @@ public final int max(final Object obj) { } /** - * Returns the minimum frequency of an object. + * Gets the minimum frequency of an object. + * * @param obj the object * @return the minimum frequency of the object */ @@ -1257,21 +1262,7 @@ public static boolean isEmpty(final Collection coll) { * @throws NullPointerException if either collection is null */ public static boolean isEqualCollection(final Collection a, final Collection b) { - Objects.requireNonNull(a, "a"); - Objects.requireNonNull(b, "b"); - if (a.size() != b.size()) { - return false; - } - final CardinalityHelper helper = new CardinalityHelper<>(a, b); - if (helper.cardinalityA.size() != helper.cardinalityB.size()) { - return false; - } - for (final Object obj : helper.cardinalityA.keySet()) { - if (helper.freqA(obj) != helper.freqB(obj)) { - return false; - } - } - return true; + return CardinalityHelper.equals(a, b); } /** diff --git a/src/main/java/org/apache/commons/collections4/FluentIterable.java b/src/main/java/org/apache/commons/collections4/FluentIterable.java index d3b07b88ac..c985d7e575 100644 --- a/src/main/java/org/apache/commons/collections4/FluentIterable.java +++ b/src/main/java/org/apache/commons/collections4/FluentIterable.java @@ -91,7 +91,7 @@ public static FluentIterable empty() { * @throws NullPointerException if iterable is null */ public static FluentIterable of(final Iterable iterable) { - IterableUtils.checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); if (iterable instanceof FluentIterable) { return (FluentIterable) iterable; } diff --git a/src/main/java/org/apache/commons/collections4/IterableUtils.java b/src/main/java/org/apache/commons/collections4/IterableUtils.java index 4b3adadca4..7066028fff 100644 --- a/src/main/java/org/apache/commons/collections4/IterableUtils.java +++ b/src/main/java/org/apache/commons/collections4/IterableUtils.java @@ -93,7 +93,7 @@ public Iterator iterator() { * @throws NullPointerException if iterable is null */ public static Iterable boundedIterable(final Iterable iterable, final long maxSize) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); if (maxSize < 0) { throw new IllegalArgumentException("MaxSize parameter must not be negative."); } @@ -219,16 +219,6 @@ public static Iterable chainedIterable(final Iterable a, return chainedIterable(new Iterable[] {a, b, c, d}); } - /** - * Fail-fast check for null arguments. - * - * @param iterable the iterable to check - * @throws NullPointerException if iterable is null - */ - static void checkNotNull(final Iterable iterable) { - Objects.requireNonNull(iterable, "iterable"); - } - /** * Fail-fast check for null arguments. * @@ -238,7 +228,7 @@ static void checkNotNull(final Iterable iterable) { static void checkNotNull(final Iterable... iterables) { Objects.requireNonNull(iterables, "iterables"); for (final Iterable iterable : iterables) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); } } @@ -409,7 +399,7 @@ private static Iterator emptyIteratorIfNull(final Iterable iterable) { */ public static Iterable filteredIterable(final Iterable iterable, final Predicate predicate) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); Objects.requireNonNull(predicate, "predicate"); return new FluentIterable() { @Override @@ -572,7 +562,7 @@ public static boolean isEmpty(final Iterable iterable) { * @throws NullPointerException if iterable is null */ public static Iterable loopingIterable(final Iterable iterable) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); return new FluentIterable() { @Override public Iterator iterator() { @@ -818,7 +808,7 @@ public static List> partition(final Iterable iterable, * @see ReverseListIterator */ public static Iterable reversedIterable(final Iterable iterable) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); return new FluentIterable() { @Override public Iterator iterator() { @@ -864,7 +854,7 @@ public static int size(final Iterable iterable) { * @throws NullPointerException if iterable is null */ public static Iterable skippingIterable(final Iterable iterable, final long elementsToSkip) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); if (elementsToSkip < 0) { throw new IllegalArgumentException("ElementsToSkip parameter must not be negative."); } @@ -970,7 +960,7 @@ public static String toString(final Iterable iterable, */ public static Iterable transformedIterable(final Iterable iterable, final Transformer transformer) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); Objects.requireNonNull(transformer, "transformer"); return new FluentIterable() { @Override @@ -994,7 +984,7 @@ public Iterator iterator() { * @throws NullPointerException if iterable is null */ public static Iterable uniqueIterable(final Iterable iterable) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); return new FluentIterable() { @Override public Iterator iterator() { @@ -1015,7 +1005,7 @@ public Iterator iterator() { * @throws NullPointerException if iterable is null */ public static Iterable unmodifiableIterable(final Iterable iterable) { - checkNotNull(iterable); + Objects.requireNonNull(iterable, "iterable"); if (iterable instanceof UnmodifiableIterable) { return iterable; } @@ -1042,8 +1032,8 @@ public static Iterable unmodifiableIterable(final Iterable iterable) { */ public static Iterable zippingIterable(final Iterable a, final Iterable b) { - checkNotNull(a); - checkNotNull(b); + Objects.requireNonNull(a, "iterable"); + Objects.requireNonNull(b, "iterable"); return new FluentIterable() { @Override public Iterator iterator() { @@ -1069,7 +1059,7 @@ public Iterator iterator() { * @throws NullPointerException if either of the provided iterables is null */ public static Iterable zippingIterable(final Iterable first, final Iterable... others) { - checkNotNull(first); + Objects.requireNonNull(first, "iterable"); checkNotNull(others); return new FluentIterable() { @Override diff --git a/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java b/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java index e9f2bfe84f..d3fa5e6e1e 100644 --- a/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java +++ b/src/main/java/org/apache/commons/collections4/bag/AbstractMapBag.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.Set; import org.apache.commons.collections4.Bag; @@ -109,10 +110,12 @@ public void remove() { canRemove = false; } } + /** * Mutable integer class for storing the data. */ protected static class MutableInteger { + /** The value of this mutable. */ protected int value; @@ -137,8 +140,10 @@ public int hashCode() { return value; } } + /** The map to use to store the data */ private transient Map map; + /** The current total size of the bag */ private int size; @@ -161,7 +166,19 @@ protected AbstractMapBag() { * @param map the map to assign */ protected AbstractMapBag(final Map map) { - this.map = map; + this.map = Objects.requireNonNull(map, "map"); + } + + /** + * Constructs a new instance that assigns the specified Map as the backing store. The map + * must be empty and non-null. The bag is filled from the iterable elements. + * + * @param map the map to assign. + * @param iterable The bag is filled from these iterable elements. + */ + protected AbstractMapBag(final Map map, final Iterable iterable) { + this(map); + iterable.forEach(this::add); } /** diff --git a/src/main/java/org/apache/commons/collections4/bag/HashBag.java b/src/main/java/org/apache/commons/collections4/bag/HashBag.java index 1335669aa1..6b33ab8b7f 100644 --- a/src/main/java/org/apache/commons/collections4/bag/HashBag.java +++ b/src/main/java/org/apache/commons/collections4/bag/HashBag.java @@ -50,13 +50,23 @@ public HashBag() { } /** - * Constructs a bag containing all the members of the given collection. + * Constructs a bag containing all the members of the given Collection. * - * @param coll a collection to copy into this bag + * @param collection a collection to copy into this bag. */ - public HashBag(final Collection coll) { + public HashBag(final Collection collection) { this(); - addAll(coll); + addAll(collection); + } + + /** + * Constructs a bag containing all the members of the given Iterable. + * + * @param iterable an iterable to copy into this bag. + * @since 4.5.0-M3 + */ + public HashBag(final Iterable iterable) { + super(new HashMap<>(), iterable); } /** diff --git a/src/main/java/org/apache/commons/collections4/bag/TreeBag.java b/src/main/java/org/apache/commons/collections4/bag/TreeBag.java index fa10f94db6..14f7a6802d 100644 --- a/src/main/java/org/apache/commons/collections4/bag/TreeBag.java +++ b/src/main/java/org/apache/commons/collections4/bag/TreeBag.java @@ -67,6 +67,16 @@ public TreeBag(final Collection coll) { addAll(coll); } + /** + * Constructs a bag containing all the members of the given Iterable. + * + * @param iterable an iterable to copy into this bag. + * @since 4.5.0-M3 + */ + public TreeBag(final Iterable iterable) { + super(new TreeMap<>(), iterable); + } + /** * Constructs an empty bag that maintains order on its unique representative * members according to the given {@link Comparator}. diff --git a/src/main/java/org/apache/commons/collections4/iterators/CartesianProductIterator.java b/src/main/java/org/apache/commons/collections4/iterators/CartesianProductIterator.java new file mode 100644 index 0000000000..a868b0942e --- /dev/null +++ b/src/main/java/org/apache/commons/collections4/iterators/CartesianProductIterator.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.collections4.iterators; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Objects; + +/** + * This iterator creates a Cartesian product of the input iterables, + * equivalent to nested for-loops. + *

+ * The iterables provided to the constructor are used in reverse order, each + * until exhaustion before proceeding to the next element of the prior iterable + * and repeating. Consider the following example: + *

+ *
{@code
+ * List iterable1 = Arrays.asList('A', 'B', 'C');
+ * List iterable2 = Arrays.asList('1', '2', '3');
+ * CartesianProductIterator it = new CartesianProductIterator<>(
+ *         iterable1,
+ *         iterable2);
+ * while (it.hasNext()) {
+ *     List tuple = it.next();
+ *     System.out.println(tuple.get(0) + ", " + tuple.get(1));
+ * }
+ * }
+ *

+ * The output will be: + *

+ *
+ * A, 1
+ * A, 2
+ * A, 3
+ * B, 1
+ * B, 2
+ * B, 3
+ * C, 1
+ * C, 2
+ * C, 3
+ * 
+ *

+ * The {@code remove()} operation is not supported, and will throw an + * {@code UnsupportedOperationException}. + *

+ *

+ * If any of the input iterables is empty, the Cartesian product will be empty. + * If any of the input iterables is infinite, the Cartesian product will be + * infinite. + *

+ * + * @param the type of the objects being permuted + * @since 4.5.0 + */ +public class CartesianProductIterator implements Iterator> { + + /** + * The iterables to create the Cartesian product from. + */ + private final List> iterables; + + /** + * The iterators to generate the Cartesian product tuple from. + */ + private final List> iterators; + + /** + * The previous generated tuple of elements. + */ + private List previousTuple; + + /** + * Constructs a new {@code CartesianProductIterator} instance with given iterables. + * + * @param iterables the iterables to create the Cartesian product from + * @throws NullPointerException if any of the iterables is null + */ + @SafeVarargs + public CartesianProductIterator(final Iterable... iterables) { + Objects.requireNonNull(iterables, "iterables"); + this.iterables = new ArrayList<>(iterables.length); + this.iterators = new ArrayList<>(iterables.length); + for (final Iterable iterable : iterables) { + Objects.requireNonNull(iterable, "iterable"); + this.iterables.add(iterable); + final Iterator iterator = iterable.iterator(); + if (!iterator.hasNext()) { + iterators.clear(); + break; + } + iterators.add(iterator); + } + } + + /** + * Returns {@code true} if the iteration has more elements. + * + * @return true if there are more tuples, otherwise false + */ + @Override + public boolean hasNext() { + return iterators.stream().anyMatch(Iterator::hasNext); + } + + /** + * Returns the next tuple of the input iterables. + * + * @return a list of the input iterables' elements + * @throws NoSuchElementException if there are no more tuples + */ + @Override + public List next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + if (previousTuple == null) { + previousTuple = new ArrayList<>(iterables.size()); + for (final Iterator iterator : iterators) { + previousTuple.add(iterator.next()); + } + return new ArrayList<>(previousTuple); + } + for (int i = iterators.size() - 1; i >= 0; i--) { + Iterator iterator = iterators.get(i); + if (iterator.hasNext()) { + previousTuple.set(i, iterator.next()); + return new ArrayList<>(previousTuple); + } + iterator = iterables.get(i).iterator(); + iterators.set(i, iterator); + previousTuple.set(i, iterator.next()); + } + throw new IllegalStateException("reached unreachable code"); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("remove"); + } +} diff --git a/src/test/java/org/apache/commons/collections4/BagUtilsTest.java b/src/test/java/org/apache/commons/collections4/BagUtilsTest.java index 1218470c4b..7de5425c2d 100644 --- a/src/test/java/org/apache/commons/collections4/BagUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/BagUtilsTest.java @@ -17,9 +17,9 @@ package org.apache.commons.collections4; import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import org.apache.commons.collections4.bag.HashBag; import org.apache.commons.collections4.bag.PredicatedBag; @@ -45,7 +45,7 @@ public class BagUtilsTest { @Test public void testPredicatedBag() { final Bag bag = BagUtils.predicatedBag(new HashBag<>(), truePredicate); - assertTrue(bag instanceof PredicatedBag, "Returned object should be a PredicatedBag."); + assertInstanceOf(PredicatedBag.class, bag, "Returned object should be a PredicatedBag."); assertAll( () -> assertThrows(NullPointerException.class, () -> BagUtils.predicatedBag(null, truePredicate), "Expecting NullPointerException for null bag."), @@ -57,7 +57,7 @@ public void testPredicatedBag() { @Test public void testPredicatedSortedBag() { final Bag bag = BagUtils.predicatedSortedBag(new TreeBag<>(), truePredicate); - assertTrue(bag instanceof PredicatedSortedBag, "Returned object should be a PredicatedSortedBag."); + assertInstanceOf(PredicatedSortedBag.class, bag, "Returned object should be a PredicatedSortedBag."); assertAll( () -> assertThrows(NullPointerException.class, () -> BagUtils.predicatedSortedBag(null, truePredicate), "Expecting NullPointerException for null bag."), @@ -69,7 +69,7 @@ public void testPredicatedSortedBag() { @Test public void testSynchronizedBag() { final Bag bag = BagUtils.synchronizedBag(new HashBag<>()); - assertTrue(bag instanceof SynchronizedBag, "Returned object should be a SynchronizedBag."); + assertInstanceOf(SynchronizedBag.class, bag, "Returned object should be a SynchronizedBag."); assertThrows(NullPointerException.class, () -> BagUtils.synchronizedBag(null), "Expecting NullPointerException for null bag."); } @@ -77,7 +77,7 @@ public void testSynchronizedBag() { @Test public void testSynchronizedSortedBag() { final Bag bag = BagUtils.synchronizedSortedBag(new TreeBag<>()); - assertTrue(bag instanceof SynchronizedSortedBag, "Returned object should be a SynchronizedSortedBag."); + assertInstanceOf(SynchronizedSortedBag.class, bag, "Returned object should be a SynchronizedSortedBag."); assertThrows(NullPointerException.class, () -> BagUtils.synchronizedSortedBag(null), "Expecting NullPointerException for null bag."); } @@ -85,7 +85,7 @@ public void testSynchronizedSortedBag() { @Test public void testTransformedBag() { final Bag bag = BagUtils.transformingBag(new HashBag<>(), nopTransformer); - assertTrue(bag instanceof TransformedBag, "Returned object should be an TransformedBag."); + assertInstanceOf(TransformedBag.class, bag, "Returned object should be an TransformedBag."); assertAll( () -> assertThrows(NullPointerException.class, () -> BagUtils.transformingBag(null, nopTransformer), "Expecting NullPointerException for null bag."), @@ -97,7 +97,7 @@ public void testTransformedBag() { @Test public void testTransformedSortedBag() { final Bag bag = BagUtils.transformingSortedBag(new TreeBag<>(), nopTransformer); - assertTrue(bag instanceof TransformedSortedBag, "Returned object should be an TransformedSortedBag"); + assertInstanceOf(TransformedSortedBag.class, bag, "Returned object should be an TransformedSortedBag"); assertAll( () -> assertThrows(NullPointerException.class, () -> BagUtils.transformingSortedBag(null, nopTransformer), "Expecting NullPointerException for null bag."), @@ -109,7 +109,7 @@ public void testTransformedSortedBag() { @Test public void testUnmodifiableBag() { final Bag bag = BagUtils.unmodifiableBag(new HashBag<>()); - assertTrue(bag instanceof UnmodifiableBag, "Returned object should be an UnmodifiableBag."); + assertInstanceOf(UnmodifiableBag.class, bag, "Returned object should be an UnmodifiableBag."); assertThrows(NullPointerException.class, () -> BagUtils.unmodifiableBag(null), "Expecting NullPointerException for null bag."); assertSame(bag, BagUtils.unmodifiableBag(bag), "UnmodifiableBag shall not be decorated"); @@ -118,7 +118,7 @@ public void testUnmodifiableBag() { @Test public void testUnmodifiableSortedBag() { final SortedBag bag = BagUtils.unmodifiableSortedBag(new TreeBag<>()); - assertTrue(bag instanceof UnmodifiableSortedBag, "Returned object should be an UnmodifiableSortedBag."); + assertInstanceOf(UnmodifiableSortedBag.class, bag, "Returned object should be an UnmodifiableSortedBag."); assertThrows(NullPointerException.class, () -> BagUtils.unmodifiableSortedBag(null), "Expecting NullPointerException for null bag."); assertSame(bag, BagUtils.unmodifiableSortedBag(bag), "UnmodifiableSortedBag shall not be decorated"); diff --git a/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java b/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java index 8113960678..cb507a0ecb 100644 --- a/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java @@ -21,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -1746,7 +1747,7 @@ public void testPermutationsWithNullCollection() { public void testPredicatedCollection() { final Predicate predicate = PredicateUtils.instanceofPredicate(Integer.class); final Collection collection = CollectionUtils.predicatedCollection(new ArrayList<>(), predicate); - assertTrue(collection instanceof PredicatedCollection, "returned object should be a PredicatedCollection"); + assertInstanceOf(PredicatedCollection.class, collection, "returned object should be a PredicatedCollection"); } @Test @@ -2321,7 +2322,7 @@ public void testSubtractWithPredicate() { @Deprecated public void testSynchronizedCollection() { final Collection col = CollectionUtils.synchronizedCollection(new ArrayList<>()); - assertTrue(col instanceof SynchronizedCollection, "Returned object should be a SynchronizedCollection."); + assertInstanceOf(SynchronizedCollection.class, col, "Returned object should be a SynchronizedCollection."); assertThrows(NullPointerException.class, () -> CollectionUtils.synchronizedCollection(null), "Expecting NullPointerException for null collection."); @@ -2366,7 +2367,7 @@ public void testTransform2() { public void testTransformedCollection() { final Transformer transformer = TransformerUtils.nopTransformer(); final Collection collection = CollectionUtils.transformingCollection(new ArrayList<>(), transformer); - assertTrue(collection instanceof TransformedCollection, "returned object should be a TransformedCollection"); + assertInstanceOf(TransformedCollection.class, collection, "returned object should be a TransformedCollection"); } @Test @@ -2430,7 +2431,7 @@ public void testUnionNullColl2() { @Deprecated public void testUnmodifiableCollection() { final Collection col = CollectionUtils.unmodifiableCollection(new ArrayList<>()); - assertTrue(col instanceof UnmodifiableCollection, "Returned object should be a UnmodifiableCollection."); + assertInstanceOf(UnmodifiableCollection.class, col, "Returned object should be a UnmodifiableCollection."); assertThrows(NullPointerException.class, () -> CollectionUtils.unmodifiableCollection(null), "Expecting NullPointerException for null collection."); diff --git a/src/test/java/org/apache/commons/collections4/ListUtilsTest.java b/src/test/java/org/apache/commons/collections4/ListUtilsTest.java index 3e9922abbe..3403f06dc9 100644 --- a/src/test/java/org/apache/commons/collections4/ListUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/ListUtilsTest.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -408,7 +409,7 @@ public void testPartition() { public void testPredicatedList() { final Predicate predicate = String.class::isInstance; final List list = ListUtils.predicatedList(new ArrayList<>(), predicate); - assertTrue(list instanceof PredicatedList, "returned object should be a PredicatedList"); + assertInstanceOf(PredicatedList.class, list, "returned object should be a PredicatedList"); assertAll( () -> assertThrows(NullPointerException.class, () -> ListUtils.predicatedList(new ArrayList<>(), null), "Expecting IllegalArgumentException for null predicate."), diff --git a/src/test/java/org/apache/commons/collections4/MapUtilsTest.java b/src/test/java/org/apache/commons/collections4/MapUtilsTest.java index 676dd231f7..d292d70409 100644 --- a/src/test/java/org/apache/commons/collections4/MapUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/MapUtilsTest.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -737,7 +738,7 @@ public void testLazyMap() { public void testLazyMapFactory() { final Factory factory = FactoryUtils.constantFactory(Integer.valueOf(5)); Map map = MapUtils.lazyMap(new HashMap<>(), factory); - assertTrue(map instanceof LazyMap); + assertInstanceOf(LazyMap.class, map); assertAll( () -> assertThrows(NullPointerException.class, () -> MapUtils.lazyMap(new HashMap<>(), (Factory) null), "Expecting NullPointerException for null factory"), @@ -747,7 +748,7 @@ public void testLazyMapFactory() { final Transformer transformer = TransformerUtils.asTransformer(factory); map = MapUtils.lazyMap(new HashMap<>(), transformer); - assertTrue(map instanceof LazyMap); + assertInstanceOf(LazyMap.class, map); assertAll( () -> assertThrows(NullPointerException.class, () -> MapUtils.lazyMap(new HashMap<>(), (Transformer) null), "Expecting NullPointerException for null transformer"), @@ -811,7 +812,7 @@ public void testOrderedMap() { inMap.put("key1", "value1"); inMap.put("key2", "value2"); final Map map = MapUtils.orderedMap(inMap); - assertTrue(map instanceof OrderedMap); + assertInstanceOf(OrderedMap.class, map); } @Test @@ -876,7 +877,7 @@ public void testPopulateMultiMap() { public void testPredicatedMap() { final Predicate p = getPredicate(); final Map map = MapUtils.predicatedMap(new HashMap<>(), p, p); - assertTrue(map instanceof PredicatedMap); + assertInstanceOf(PredicatedMap.class, map); assertThrows(NullPointerException.class, () -> MapUtils.predicatedMap(null, p, p), "Expecting NullPointerException for null map."); diff --git a/src/test/java/org/apache/commons/collections4/QueueUtilsTest.java b/src/test/java/org/apache/commons/collections4/QueueUtilsTest.java index ca8521ceaa..268e3dfb81 100644 --- a/src/test/java/org/apache/commons/collections4/QueueUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/QueueUtilsTest.java @@ -16,6 +16,7 @@ */ package org.apache.commons.collections4; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -41,7 +42,7 @@ public class QueueUtilsTest { @Test public void testEmptyQueue() { final Queue queue = QueueUtils.emptyQueue(); - assertTrue(queue instanceof UnmodifiableQueue, "Returned object should be an UnmodifiableQueue."); + assertInstanceOf(UnmodifiableQueue.class, queue, "Returned object should be an UnmodifiableQueue."); assertTrue(queue.isEmpty(), "Returned queue is not empty."); assertThrows(UnsupportedOperationException.class, () -> queue.add(new Object()), @@ -51,7 +52,7 @@ public void testEmptyQueue() { @Test public void testPredicatedQueue() { final Queue queue = QueueUtils.predicatedQueue(new LinkedList<>(), truePredicate); - assertTrue(queue instanceof PredicatedQueue, "Returned object should be a PredicatedQueue."); + assertInstanceOf(PredicatedQueue.class, queue, "Returned object should be a PredicatedQueue."); assertThrows(NullPointerException.class, () -> QueueUtils.predicatedQueue(null, truePredicate), "Expecting NullPointerException for null queue."); @@ -63,7 +64,7 @@ public void testPredicatedQueue() { @Test public void testSynchronizedQueue() { final Queue queue = QueueUtils.synchronizedQueue(new LinkedList<>()); - assertTrue(queue instanceof SynchronizedQueue, "Returned object should be a SynchronizedQueue."); + assertInstanceOf(SynchronizedQueue.class, queue, "Returned object should be a SynchronizedQueue."); assertThrows(NullPointerException.class, () -> QueueUtils.synchronizedQueue(null), "Expecting NullPointerException for null queue."); @@ -72,7 +73,7 @@ public void testSynchronizedQueue() { @Test public void testTransformedQueue() { final Queue queue = QueueUtils.transformingQueue(new LinkedList<>(), nopTransformer); - assertTrue(queue instanceof TransformedQueue, "Returned object should be an TransformedQueue."); + assertInstanceOf(TransformedQueue.class, queue, "Returned object should be an TransformedQueue."); assertThrows(NullPointerException.class, () -> QueueUtils.transformingQueue(null, nopTransformer), "Expecting NullPointerException for null queue."); @@ -84,7 +85,7 @@ public void testTransformedQueue() { @Test public void testUnmodifiableQueue() { final Queue queue = QueueUtils.unmodifiableQueue(new LinkedList<>()); - assertTrue(queue instanceof UnmodifiableQueue, "Returned object should be an UnmodifiableQueue."); + assertInstanceOf(UnmodifiableQueue.class, queue, "Returned object should be an UnmodifiableQueue."); assertThrows(NullPointerException.class, () -> QueueUtils.unmodifiableQueue(null), "Expecting NullPointerException for null queue."); diff --git a/src/test/java/org/apache/commons/collections4/SetUtilsTest.java b/src/test/java/org/apache/commons/collections4/SetUtilsTest.java index b3cc533379..7a1b8dd604 100644 --- a/src/test/java/org/apache/commons/collections4/SetUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/SetUtilsTest.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -210,7 +211,7 @@ public void testNewIdentityHashSet() { public void testpredicatedSet() { final Predicate predicate = String.class::isInstance; final Set set = SetUtils.predicatedSet(new HashSet<>(), predicate); - assertTrue(set instanceof PredicatedSet, "returned object should be a PredicatedSet"); + assertInstanceOf(PredicatedSet.class, set, "returned object should be a PredicatedSet"); assertAll( () -> assertThrows(NullPointerException.class, () -> SetUtils.predicatedSet(new HashSet<>(), null), "Expecting NullPointerException for null predicate."), diff --git a/src/test/java/org/apache/commons/collections4/SplitMapUtilsTest.java b/src/test/java/org/apache/commons/collections4/SplitMapUtilsTest.java index fcf312714a..50425406e0 100644 --- a/src/test/java/org/apache/commons/collections4/SplitMapUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/SplitMapUtilsTest.java @@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -93,7 +94,7 @@ public void testReadableMap() { } // unmodifiable - assertTrue(map instanceof Unmodifiable); + assertInstanceOf(Unmodifiable.class, map); // check individual operations int sz = map.size(); diff --git a/src/test/java/org/apache/commons/collections4/TrieUtilsTest.java b/src/test/java/org/apache/commons/collections4/TrieUtilsTest.java index ec6ab5729a..3b5bc04422 100644 --- a/src/test/java/org/apache/commons/collections4/TrieUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/TrieUtilsTest.java @@ -16,9 +16,9 @@ */ package org.apache.commons.collections4; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import org.apache.commons.collections4.trie.PatriciaTrie; import org.apache.commons.collections4.trie.UnmodifiableTrie; @@ -32,7 +32,7 @@ public class TrieUtilsTest { @Test public void testUnmodifiableTrie() { final Trie trie = TrieUtils.unmodifiableTrie(new PatriciaTrie<>()); - assertTrue(trie instanceof UnmodifiableTrie, "Returned object should be an UnmodifiableTrie."); + assertInstanceOf(UnmodifiableTrie.class, trie, "Returned object should be an UnmodifiableTrie."); assertThrows(NullPointerException.class, () -> TrieUtils.unmodifiableTrie(null)); diff --git a/src/test/java/org/apache/commons/collections4/comparators/AbstractComparatorTest.java b/src/test/java/org/apache/commons/collections4/comparators/AbstractComparatorTest.java index f26196a8ea..4759e5d20b 100644 --- a/src/test/java/org/apache/commons/collections4/comparators/AbstractComparatorTest.java +++ b/src/test/java/org/apache/commons/collections4/comparators/AbstractComparatorTest.java @@ -17,7 +17,7 @@ package org.apache.commons.collections4.comparators; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.fail; import java.io.FileNotFoundException; @@ -159,7 +159,7 @@ public void testComparatorCompatibility() throws IOException, ClassNotFoundExcep @Test public void testComparatorIsSerializable() { final Comparator comparator = makeObject(); - assertTrue(comparator instanceof Serializable, + assertInstanceOf(Serializable.class, comparator, "This comparator should be Serializable."); } diff --git a/src/test/java/org/apache/commons/collections4/iterators/CartesianProductIteratorTest.java b/src/test/java/org/apache/commons/collections4/iterators/CartesianProductIteratorTest.java new file mode 100644 index 0000000000..b32eeb7267 --- /dev/null +++ b/src/test/java/org/apache/commons/collections4/iterators/CartesianProductIteratorTest.java @@ -0,0 +1,209 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.commons.collections4.iterators; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + + +/** + * Test class for {@link CartesianProductIterator}. + */ +public class CartesianProductIteratorTest extends AbstractIteratorTest> { + + private List letters; + private List numbers; + private List symbols; + private List emptyList; + + public CartesianProductIteratorTest() { + super(CartesianProductIteratorTest.class.getSimpleName()); + } + + @Override + public CartesianProductIterator makeEmptyIterator() { + return new CartesianProductIterator<>(); + } + + @Override + public CartesianProductIterator makeObject() { + return new CartesianProductIterator<>(letters, numbers, symbols); + } + + @BeforeEach + public void setUp() { + letters = Arrays.asList('A', 'B', 'C'); + numbers = Arrays.asList('1', '2', '3'); + symbols = Arrays.asList('!', '?'); + emptyList = Collections.emptyList(); + } + + @Override + public boolean supportsRemove() { + return false; + } + + @Test + public void testRemoveThrows() { + final CartesianProductIterator it = makeObject(); + assertThrows(UnsupportedOperationException.class, it::remove); + } + + @Test + public void testEmptyCollection() { + final CartesianProductIterator it = new CartesianProductIterator<>(letters, Collections.emptyList()); + assertFalse(it.hasNext()); + assertThrows(NoSuchElementException.class, it::next); + } + + /** + * test checking that all the tuples are returned + */ + @Test + public void testExhaustivity() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = makeObject(); + while (it.hasNext()) { + final List tuple = it.next(); + resultsList.add(tuple.toArray(new Character[0])); + } + assertThrows(NoSuchElementException.class, it::next); + assertEquals(18, resultsList.size()); + final Iterator itResults = resultsList.iterator(); + for (final Character a : letters) { + for (final Character b : numbers) { + for (final Character c : symbols) { + assertArrayEquals(new Character[]{a, b, c}, itResults.next()); + } + } + } + } + + /** + * test checking that no tuples are returned when at least one of the lists is empty + */ + @Test + public void testExhaustivityWithEmptyList() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = new CartesianProductIterator<>(letters, emptyList, symbols); + while (it.hasNext()) { + final List tuple = it.next(); + resultsList.add(tuple.toArray(new Character[0])); + } + assertThrows(NoSuchElementException.class, it::next); + assertEquals(0, resultsList.size()); + } + + /** + * test checking that no tuples are returned when first of the lists is empty + */ + @Test + public void testExhaustivityWithEmptyFirstList() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = new CartesianProductIterator<>(emptyList, numbers, symbols); + while (it.hasNext()) { + final List tuple = it.next(); + resultsList.add(tuple.toArray(new Character[0])); + } + assertThrows(NoSuchElementException.class, it::next); + assertEquals(0, resultsList.size()); + } + + /** + * test checking that no tuples are returned when last of the lists is empty + */ + @Test + public void testExhaustivityWithEmptyLastList() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = new CartesianProductIterator<>(letters, numbers, emptyList); + while (it.hasNext()) { + final List tuple = it.next(); + resultsList.add(tuple.toArray(new Character[0])); + } + assertThrows(NoSuchElementException.class, it::next); + assertEquals(0, resultsList.size()); + } + + /** + * test checking that no tuples are returned when all the lists are empty + */ + @Test + public void testExhaustivityWithAllEmptyLists() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = new CartesianProductIterator<>(emptyList, emptyList, emptyList); + while (it.hasNext()) { + final List tuple = it.next(); + resultsList.add(tuple.toArray(new Character[0])); + } + assertThrows(NoSuchElementException.class, it::next); + assertEquals(0, resultsList.size()); + } + + /** + * test checking that all tuples are returned when same list is passed multiple times + */ + @Test + public void testExhaustivityWithSameList() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = new CartesianProductIterator<>(letters, letters, letters); + while (it.hasNext()) { + final List tuple = it.next(); + resultsList.add(tuple.toArray(new Character[0])); + } + assertThrows(NoSuchElementException.class, it::next); + assertEquals(27, resultsList.size()); + final Iterator itResults = resultsList.iterator(); + for (final Character a : letters) { + for (final Character b : letters) { + for (final Character c : letters) { + assertArrayEquals(new Character[]{a, b, c}, itResults.next()); + } + } + } + } + + /** + * test that all tuples are provided to consumer + */ + @Test + public void testForEachRemaining() { + final List resultsList = new ArrayList<>(); + final CartesianProductIterator it = makeObject(); + it.forEachRemaining(tuple -> resultsList.add(tuple.toArray(new Character[0]))); + assertEquals(18, resultsList.size()); + final Iterator itResults = resultsList.iterator(); + for (final Character a : letters) { + for (final Character b : numbers) { + for (final Character c : symbols) { + assertArrayEquals(new Character[]{a, b, c}, itResults.next()); + } + } + } + } +} diff --git a/src/test/java/org/apache/commons/collections4/keyvalue/UnmodifiableMapEntryTest.java b/src/test/java/org/apache/commons/collections4/keyvalue/UnmodifiableMapEntryTest.java index 095473528a..a6be43ba1d 100644 --- a/src/test/java/org/apache/commons/collections4/keyvalue/UnmodifiableMapEntryTest.java +++ b/src/test/java/org/apache/commons/collections4/keyvalue/UnmodifiableMapEntryTest.java @@ -16,9 +16,9 @@ */ package org.apache.commons.collections4.keyvalue; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Map; @@ -89,7 +89,7 @@ public void testConstructors() { assertSame(key, entry2.getKey()); assertSame(value, entry2.getValue()); - assertTrue(entry instanceof Unmodifiable); + assertInstanceOf(Unmodifiable.class, entry); } @Test diff --git a/src/test/java/org/apache/commons/collections4/map/LazySortedMapTest.java b/src/test/java/org/apache/commons/collections4/map/LazySortedMapTest.java index 007ae2e562..418e1fccd9 100644 --- a/src/test/java/org/apache/commons/collections4/map/LazySortedMapTest.java +++ b/src/test/java/org/apache/commons/collections4/map/LazySortedMapTest.java @@ -19,10 +19,10 @@ import static org.apache.commons.collections4.map.LazySortedMap.lazySortedMap; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Comparator; import java.util.Map; @@ -133,7 +133,7 @@ public void testSortOrder() { public void testTransformerDecorate() { final Transformer transformer = TransformerUtils.asTransformer(oneFactory); final SortedMap map = lazySortedMap(new TreeMap<>(), transformer); - assertTrue(map instanceof LazySortedMap); + assertInstanceOf(LazySortedMap.class, map); assertAll( () -> assertThrows(NullPointerException.class, () -> lazySortedMap(new TreeMap<>(), (Transformer) null), "Expecting NullPointerException for null transformer"), diff --git a/src/test/java/org/apache/commons/collections4/map/SingletonMapTest.java b/src/test/java/org/apache/commons/collections4/map/SingletonMapTest.java index 7141f23ab3..dfd074ab92 100644 --- a/src/test/java/org/apache/commons/collections4/map/SingletonMapTest.java +++ b/src/test/java/org/apache/commons/collections4/map/SingletonMapTest.java @@ -17,6 +17,7 @@ package org.apache.commons.collections4.map; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.HashMap; @@ -101,7 +102,7 @@ public void testBoundedMap() { assertEquals(1, map.size()); assertTrue(map.isFull()); assertEquals(1, map.maxSize()); - assertTrue(map instanceof BoundedMap); + assertInstanceOf(BoundedMap.class, map); } @Test @@ -167,7 +168,7 @@ public void testKeyValue() { assertEquals(1, map.size()); assertEquals(ONE, map.getKey()); assertEquals(TWO, map.getValue()); - assertTrue(map instanceof KeyValue); + assertInstanceOf(KeyValue.class, map); } // public void testCreate() throws Exception { diff --git a/src/test/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMapTest.java b/src/test/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMapTest.java index ac80948e2e..b2905b98f1 100644 --- a/src/test/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMapTest.java +++ b/src/test/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMapTest.java @@ -931,7 +931,7 @@ public void testKeysBagContainsAll() { } @Test - public void testKeysBagIterator() { + public void testKeysBagIterator1() { final MultiValuedMap map = makeFullMap(); final Collection col = new ArrayList<>(map.keys()); final Bag bag = new HashBag<>(col); @@ -942,6 +942,18 @@ public void testKeysBagIterator() { assertEquals(getSampleTotalValueCount(), bag.size()); } + @Test + public void testKeysBagIterator2() { + final MultiValuedMap map = makeFullMap(); + final Iterable iterable = new ArrayList<>(map.keys()); + final Bag bag = new HashBag<>(iterable); + final int maxK = getSampleKeySize(); + for (int k = 0; k < maxK; k++) { + assertEquals(getSampleCountPerKey(), bag.getCount(makeKey(k))); + } + assertEquals(getSampleTotalValueCount(), bag.size()); + } + @Test public void testKeySetSize() { final MultiValuedMap map = makeFullMap();