This is an automated email from the ASF dual-hosted git repository.
garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-collections.git
The following commit(s) were added to refs/heads/master by this push:
new 572f9be73 Refactor summing sizes for duplication
572f9be73 is described below
commit 572f9be73d743cc3d360581f18680859c6a45b96
Author: Gary Gregory <[email protected]>
AuthorDate: Fri Jul 10 15:32:55 2026 -0400
Refactor summing sizes for duplication
- Fail faster
- Add IterableUtils.sumSizesToInt(Iterable<? extends Collection<E>>)
---
src/changes/changes.xml | 1 +
.../apache/commons/collections4/IterableUtils.java | 39 ++++++++++++++++++++++
.../collection/CompositeCollection.java | 7 ++--
.../multimap/AbstractMultiValuedMap.java | 7 ++--
.../collections4/multiset/AbstractMultiSet.java | 16 +++++----
.../commons/collections4/set/CompositeSet.java | 7 ++--
.../multimap/AbstractMultiValuedMapTest.java | 1 +
7 files changed, 57 insertions(+), 21 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index d4ddb86b7..593148abe 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -85,6 +85,7 @@
<action type="add" dev="ggregory" due-to="Gary Gregory">Add a Maven
benchmark profile for JMH.</action>
<action type="add" issue="COLLECTIONS-893" dev="paulk" due-to="Paul
King">Add SortedMultiSet interface, TreeMultiSet implementation, sorted
multiset decorators, and MultiSetUtils factory methods, giving MultiSet feature
parity with SortedBag/TreeBag.</action>
<action type="add" issue="COLLECTIONS-893" dev="paulk" due-to="Paul
King">Add MultiSetUtils.containsOccurrences/removeOccurrences/retainOccurrences
providing Bag's cardinality-respecting semantics under explicit names, and
Bag-to-MultiSet migration notes in the Bag javadoc.</action>
+ <action type="add" dev="ggregory" due-to="Gary Gregory">Add
IterableUtils.sumSizes(Iterable<? extends Collection<E>>).</action>
<!-- UPDATE -->
<action type="update" dev="ggregory" due-to="Gary Gregory,
Dependabot">Bump org.apache.commons:commons-parent from 81 to 102 #612, #645,
#662, #663.</action>
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump
com.google.guava:guava-testlib from 33.3.1-jre to 33.5.0-jre #644.</action>
diff --git a/src/main/java/org/apache/commons/collections4/IterableUtils.java
b/src/main/java/org/apache/commons/collections4/IterableUtils.java
index 133b8a93e..4475ffff6 100644
--- a/src/main/java/org/apache/commons/collections4/IterableUtils.java
+++ b/src/main/java/org/apache/commons/collections4/IterableUtils.java
@@ -26,6 +26,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
+import java.util.function.ToIntFunction;
import org.apache.commons.collections4.functors.EqualPredicate;
import org.apache.commons.collections4.functors.NullPredicate;
@@ -927,6 +928,44 @@ public class IterableUtils {
};
}
+ /**
+ * Returns the sum of the sizes of the collections in the given iterable.
+ * <p>
+ * Integer overflow is capped at {@link Integer#MAX_VALUE}.
+ * </p>
+ *
+ * @param <E> The element type of the collections in the iterable.
+ * @param iterable the iterable of collections to sum the sizes of, must
not be null.
+ * @return the sum of the sizes of the collections in the iterable, capped
at {@link Integer#MAX_VALUE}.
+ * @since 4.6.0
+ */
+ public static <E> int sumSizesToInt(final Iterable<? extends
Collection<E>> iterable) {
+ return sumToInt(iterable, Collection::size);
+ }
+
+ /**
+ * Returns the sum of the integer values produced by applying the given
function to each element in the iterable.
+ * <p>
+ * Integer overflow is capped at {@link Integer#MAX_VALUE}.
+ * </p>
+ *
+ * @param <C> The type of the elements in the iterable.
+ * @param iterable The iterable of elements to sum the integer values
of, must not be null.
+ * @param toIntFunction The function to apply to each element to produce
an integer value, must not be null.
+ * @return the sum of the integer values produced by applying the function
to each element in the iterable, capped at {@link Integer#MAX_VALUE}.
+ */
+ private static <C extends Collection<?>> int sumToInt(final Iterable<C>
iterable, final ToIntFunction<C> toIntFunction) {
+ int size = 0;
+ try {
+ for (final C item : iterable) {
+ size = Math.addExact(size, toIntFunction.applyAsInt(item));
+ }
+ } catch (final ArithmeticException e) {
+ size = Integer.MAX_VALUE;
+ }
+ return size;
+ }
+
/**
* Gets a new list with the contents of the provided iterable.
*
diff --git
a/src/main/java/org/apache/commons/collections4/collection/CompositeCollection.java
b/src/main/java/org/apache/commons/collections4/collection/CompositeCollection.java
index 486e132b1..85cc3baa2 100644
---
a/src/main/java/org/apache/commons/collections4/collection/CompositeCollection.java
+++
b/src/main/java/org/apache/commons/collections4/collection/CompositeCollection.java
@@ -27,6 +27,7 @@ import java.util.function.Predicate;
import java.util.stream.Stream;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.iterators.EmptyIterator;
import org.apache.commons.collections4.iterators.IteratorChain;
import org.apache.commons.collections4.list.UnmodifiableList;
@@ -430,11 +431,7 @@ public class CompositeCollection<E> implements
Collection<E>, Serializable {
*/
@Override
public int size() {
- long size = 0;
- for (final Collection<E> item : all) {
- size += item.size();
- }
- return (int) Math.min(size, Integer.MAX_VALUE);
+ return IterableUtils.sumSizesToInt(all);
}
/**
diff --git
a/src/main/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMap.java
b/src/main/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMap.java
index 373f68716..cf8094f07 100644
---
a/src/main/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMap.java
+++
b/src/main/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMap.java
@@ -31,6 +31,7 @@ import java.util.Objects;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.IteratorUtils;
import org.apache.commons.collections4.MapIterator;
import org.apache.commons.collections4.MultiSet;
@@ -903,11 +904,7 @@ public abstract class AbstractMultiValuedMap<K, V>
implements MultiValuedMap<K,
// but this requires that all modifications of the multimap
// (including the wrapped collections and entry/value
// collections) are tracked.
- long size = 0;
- for (final Collection<V> col : getMap().values()) {
- size += col.size();
- }
- return (int) Math.min(size, Integer.MAX_VALUE);
+ return IterableUtils.sumSizesToInt(getMap().values());
}
@Override
diff --git
a/src/main/java/org/apache/commons/collections4/multiset/AbstractMultiSet.java
b/src/main/java/org/apache/commons/collections4/multiset/AbstractMultiSet.java
index 7de3788a5..ba6b739b9 100644
---
a/src/main/java/org/apache/commons/collections4/multiset/AbstractMultiSet.java
+++
b/src/main/java/org/apache/commons/collections4/multiset/AbstractMultiSet.java
@@ -475,16 +475,20 @@ public abstract class AbstractMultiSet<E> extends
AbstractCollection<E> implemen
/**
* Returns the number of elements in this multiset.
*
- * @return current size of the multiset, or {@code Integer.MAX_VALUE}
- * if the total exceeds it
+ * @return current size of the multiset, or {@code Integer.MAX_VALUE} if
the total exceeds it.
*/
@Override
public int size() {
- long totalSize = 0;
- for (final Entry<E> entry : entrySet()) {
- totalSize += entry.getCount();
+ // TODO reuse IterableUtils.sum(Iterable, ToIntFunction)
+ int size = 0;
+ try {
+ for (final Entry<E> entry : entrySet()) {
+ size = Math.addExact(size, entry.getCount());
+ }
+ } catch (final ArithmeticException e) {
+ size = Integer.MAX_VALUE;
}
- return (int) Math.min(totalSize, Integer.MAX_VALUE);
+ return size;
}
/**
diff --git
a/src/main/java/org/apache/commons/collections4/set/CompositeSet.java
b/src/main/java/org/apache/commons/collections4/set/CompositeSet.java
index 290606e29..5b3bed7bd 100644
--- a/src/main/java/org/apache/commons/collections4/set/CompositeSet.java
+++ b/src/main/java/org/apache/commons/collections4/set/CompositeSet.java
@@ -28,6 +28,7 @@ import java.util.Set;
import java.util.function.Predicate;
import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.collection.CompositeCollection;
import org.apache.commons.collections4.iterators.EmptyIterator;
import org.apache.commons.collections4.iterators.IteratorChain;
@@ -470,11 +471,7 @@ public class CompositeSet<E> implements Set<E>,
Serializable {
*/
@Override
public int size() {
- long size = 0;
- for (final Set<E> item : all) {
- size += item.size();
- }
- return (int) Math.min(size, Integer.MAX_VALUE);
+ return IterableUtils.sumSizesToInt(all);
}
/**
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 46588a3d1..ed9663541 100644
---
a/src/test/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMapTest.java
+++
b/src/test/java/org/apache/commons/collections4/multimap/AbstractMultiValuedMapTest.java
@@ -1293,6 +1293,7 @@ public abstract class AbstractMultiValuedMapTest<K, V>
extends AbstractObjectTes
map.put("k2", "v2");
((HashBag<String>) map.getMap().get("k1")).add("v1", Integer.MAX_VALUE
- 1);
((HashBag<String>) map.getMap().get("k2")).add("v2", Integer.MAX_VALUE
- 1);
+ ((HashBag<String>) map.getMap().get("k1")).add("v1", Integer.MAX_VALUE
- 1);
assertEquals(Integer.MAX_VALUE, map.size());
}