Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.apache.commons.collections4.bag.HashBag;
import org.apache.commons.collections4.collection.PredicatedCollection;
import org.apache.commons.collections4.collection.SynchronizedCollection;
import org.apache.commons.collections4.collection.TransformedCollection;
import org.apache.commons.collections4.collection.UnmodifiableBoundedCollection;
import org.apache.commons.collections4.collection.UnmodifiableCollection;
import org.apache.commons.collections4.functors.TruePredicate;
import org.apache.commons.collections4.iterators.CollatingIterator;
import org.apache.commons.collections4.iterators.PermutationIterator;
/**
* Provides utility methods and decorators for {@link Collection} instances.
*
* Various utility methods might put the input objects into a Set/Map/Bag. In case
* the input objects override {@link Object#equals(Object)}, it is mandatory that
* the general contract of the {@link Object#hashCode()} method is maintained.
*
*
* NOTE: From 4.0, method parameters will take {@link Iterable} objects when possible.
*
*
* @since 1.0
*/
public class CollectionUtils {
/**
* Helper class to easily access cardinality properties of two collections.
* @param the element type
*/
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 Bag cardinalityA;
/** Contains the cardinality for each object in collection B. */
final Bag cardinalityB;
/**
* Creates a new CardinalityHelper for two collections.
*
* @param a the first collection
* @param b the second collection
*/
CardinalityHelper(final Iterable extends O> a, final Iterable extends O> b) {
cardinalityA = new HashBag<>(a);
cardinalityB = new HashBag<>(b);
}
/**
* 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 key) {
return getFreq(key, cardinalityA);
}
/**
* 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 key) {
return getFreq(key, cardinalityB);
}
private int getFreq(final Object key, final Bag> freqMap) {
return freqMap.getCount(key);
}
/**
* Gets the maximum frequency of an object.
*
* @param obj the object
* @return the maximum frequency of the object
*/
public final int max(final Object obj) {
return Math.max(freqA(obj), freqB(obj));
}
/**
* Gets the minimum frequency of an object.
*
* @param obj the object
* @return the minimum frequency of the object
*/
public final int min(final Object obj) {
return Math.min(freqA(obj), freqB(obj));
}
}
/**
* Wraps another object and uses the provided Equator to implement
* {@link #equals(Object)} and {@link #hashCode()}.
*
* This class can be used to store objects into a Map.
*
*
* @param the element type
* @since 4.0
*/
private static final class EquatorWrapper {
private final Equator super O> equator;
private final O object;
EquatorWrapper(final Equator super O> equator, final O object) {
this.equator = equator;
this.object = object;
}
@Override
public boolean equals(final Object obj) {
if (!(obj instanceof EquatorWrapper)) {
return false;
}
@SuppressWarnings("unchecked")
final EquatorWrapper otherObj = (EquatorWrapper) obj;
return equator.equate(object, otherObj.getObject());
}
public O getObject() {
return object;
}
@Override
public int hashCode() {
return equator.hash(object);
}
}
/**
* Helper class for set-related operations, e.g. union, subtract, intersection.
* @param the element type
*/
private static final class SetOperationCardinalityHelper extends CardinalityHelper implements Iterable {
/** Contains the unique elements of the two collections. */
private final Set elements;
/** Output collection. */
private final List newList;
/**
* Create a new set operation helper from the two collections.
* @param a the first collection
* @param b the second collection
*/
SetOperationCardinalityHelper(final Iterable extends O> a, final Iterable extends O> b) {
super(a, b);
elements = new HashSet<>();
addAll(elements, a);
addAll(elements, b);
// the resulting list must contain at least each unique element, but may grow
newList = new ArrayList<>(elements.size());
}
@Override
public Iterator iterator() {
return elements.iterator();
}
/**
* Returns the resulting collection.
* @return the result
*/
public Collection list() {
return newList;
}
/**
* Add the object {@code count} times to the result collection.
* @param obj the object to add
* @param count the count
*/
public void setCardinality(final O obj, final int count) {
for (int i = 0; i < count; i++) {
newList.add(obj);
}
}
}
/**
* The index value when an element is not found in a collection or array: {@code -1}.
*
* @since 4.5.0-M1
*/
public static final int INDEX_NOT_FOUND = -1;
/**
* Default prefix used while converting an Iterator to its String representation.
*
* @since 4.5.0-M1
*/
public static final String DEFAULT_TOSTRING_PREFIX = "[";
/**
* Default suffix used while converting an Iterator to its String representation.
*
* @since 4.5.0-M1
*/
public static final String DEFAULT_TOSTRING_SUFFIX = "]";
/**
* A String for Colon (":").
*
* @since 4.5.0-M1
*/
public static final String COLON = ":";
/**
* A String for Comma (",").
*
* @since 4.5.0-M1
*/
public static final String COMMA = ",";
/**
* An empty unmodifiable collection.
* The JDK provides empty Set and List implementations which could be used for
* this purpose. However they could be cast to Set or List which might be
* undesirable. This implementation only implements Collection.
*/
@SuppressWarnings("rawtypes") // we deliberately use the raw type here
public static final Collection EMPTY_COLLECTION = Collections.emptyList();
/**
* Adds all elements in the array to the given collection.
*
* @param the type of object the {@link Collection} contains
* @param collection the collection to add to, must not be null
* @param elements the array of elements to add, must not be null
* @return {@code true} if the collection was changed, {@code false} otherwise
* @throws NullPointerException if the collection or elements is null
*/
public static boolean addAll(final Collection collection, final C... elements) {
Objects.requireNonNull(collection, "collection");
Objects.requireNonNull(elements, "elements");
boolean changed = false;
for (final C element : elements) {
changed |= collection.add(element);
}
return changed;
}
/**
* Adds all elements in the enumeration to the given collection.
*
* @param the type of object the {@link Collection} contains
* @param collection the collection to add to, must not be null
* @param enumeration the enumeration of elements to add, must not be null
* @return {@code true} if the collections was changed, {@code false} otherwise
* @throws NullPointerException if the collection or enumeration is null
*/
public static boolean addAll(final Collection collection, final Enumeration extends C> enumeration) {
Objects.requireNonNull(collection, "collection");
Objects.requireNonNull(enumeration, "enumeration");
boolean changed = false;
while (enumeration.hasMoreElements()) {
changed |= collection.add(enumeration.nextElement());
}
return changed;
}
/**
* Adds all elements in the {@link Iterable} to the given collection. If the
* {@link Iterable} is a {@link Collection} then it is cast and will be
* added using {@link Collection#addAll(Collection)} instead of iterating.
*
* @param the type of object the {@link Collection} contains
* @param collection the collection to add to, must not be null
* @param iterable the iterable of elements to add, must not be null
* @return a boolean indicating whether the collection has changed or not.
* @throws NullPointerException if the collection or iterable is null
*/
public static boolean addAll(final Collection collection, final Iterable extends C> iterable) {
Objects.requireNonNull(collection, "collection");
Objects.requireNonNull(iterable, "iterable");
if (iterable instanceof Collection>) {
return collection.addAll((Collection extends C>) iterable);
}
return addAll(collection, iterable.iterator());
}
/**
* Adds all elements in the iteration to the given collection.
*
* @param the type of object the {@link Collection} contains
* @param collection the collection to add to, must not be null
* @param iterator the iterator of elements to add, must not be null
* @return a boolean indicating whether the collection has changed or not.
* @throws NullPointerException if the collection or iterator is null
*/
public static boolean addAll(final Collection collection, final Iterator extends C> iterator) {
Objects.requireNonNull(collection, "collection");
Objects.requireNonNull(iterator, "iterator");
boolean changed = false;
while (iterator.hasNext()) {
changed |= collection.add(iterator.next());
}
return changed;
}
/**
* Adds an element to the collection unless the element is null.
*
* @param the type of object the {@link Collection} contains
* @param collection the collection to add to, must not be null
* @param object the object to add, if null it will not be added
* @return true if the collection changed
* @throws NullPointerException if the collection is null
* @since 3.2
*/
public static boolean addIgnoreNull(final Collection collection, final T object) {
Objects.requireNonNull(collection, "collection");
return object != null && collection.add(object);
}
/**
* Returns the number of occurrences of obj in coll.
*
* @param obj the object to find the cardinality of
* @param collection the {@link Iterable} to search
* @param the type of object that the {@link Iterable} may contain.
* @return the number of occurrences of obj in coll
* @throws NullPointerException if collection is null
* @deprecated since 4.1, use {@link IterableUtils#frequency(Iterable, Object)} instead.
* Be aware that the order of parameters has changed.
*/
@Deprecated
public static int cardinality(final O obj, final Iterable super O> collection) {
return IterableUtils.frequency(Objects.requireNonNull(collection, "collection"), obj);
}
/**
* Ensures an index is not negative.
* @param index the index to check.
* @throws IndexOutOfBoundsException if the index is negative.
*/
static void checkIndexBounds(final int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("Index cannot be negative: " + index);
}
}
/**
* Merges two sorted Collections, a and b, into a single, sorted List
* such that the natural ordering of the elements is retained.
*
* Uses the standard O(n) merge algorithm for combining two sorted lists.
*
*
* @param the element type
* @param a the first collection, must not be null
* @param b the second collection, must not be null
* @return a new sorted List, containing the elements of Collection a and b
* @throws NullPointerException if either collection is null
* @since 4.0
*/
public static > List collate(final Iterable extends O> a,
final Iterable extends O> b) {
return collate(a, b, ComparatorUtils.naturalComparator(), true);
}
/**
* Merges two sorted Collections, a and b, into a single, sorted List
* such that the natural ordering of the elements is retained.
*
* Uses the standard O(n) merge algorithm for combining two sorted lists.
*
*
* @param the element type
* @param a the first collection, must not be null
* @param b the second collection, must not be null
* @param includeDuplicates if {@code true} duplicate elements will be retained, otherwise
* they will be removed in the output collection
* @return a new sorted List, containing the elements of Collection a and b
* @throws NullPointerException if either collection is null
* @since 4.0
*/
public static > List collate(final Iterable extends O> a,
final Iterable extends O> b,
final boolean includeDuplicates) {
return collate(a, b, ComparatorUtils.naturalComparator(), includeDuplicates);
}
/**
* Merges two sorted Collections, a and b, into a single, sorted List
* such that the ordering of the elements according to Comparator c is retained.
*
* Uses the standard O(n) merge algorithm for combining two sorted lists.
*
*
* @param the element type
* @param a the first collection, must not be null
* @param b the second collection, must not be null
* @param c the comparator to use for the merge.
* @return a new sorted List, containing the elements of Collection a and b
* @throws NullPointerException if either collection or the comparator is null
* @since 4.0
*/
public static List collate(final Iterable extends O> a, final Iterable extends O> b,
final Comparator super O> c) {
return collate(a, b, c, true);
}
/**
* Merges two sorted Collections, a and b, into a single, sorted List
* such that the ordering of the elements according to Comparator c is retained.
*
* Uses the standard O(n) merge algorithm for combining two sorted lists.
*
*
* @param the element type
* @param iterableA the first collection, must not be null
* @param iterableB the second collection, must not be null
* @param comparator the comparator to use for the merge.
* @param includeDuplicates if {@code true} duplicate elements will be retained, otherwise
* they will be removed in the output collection
* @return a new sorted List, containing the elements of Collection a and b
* @throws NullPointerException if either collection or the comparator is null
* @since 4.0
*/
public static List collate(final Iterable extends O> iterableA, final Iterable extends O> iterableB,
final Comparator super O> comparator, final boolean includeDuplicates) {
Objects.requireNonNull(iterableA, "iterableA");
Objects.requireNonNull(iterableB, "iterableB");
Objects.requireNonNull(comparator, "comparator");
// if both Iterables are a Collection, we can estimate the size
final int totalSize = iterableA instanceof Collection> && iterableB instanceof Collection> ?
Math.max(1, ((Collection>) iterableA).size() + ((Collection>) iterableB).size()) : 10;
final Iterator iterator = new CollatingIterator<>(comparator, iterableA.iterator(), iterableB.iterator());
if (includeDuplicates) {
return IteratorUtils.toList(iterator, totalSize);
}
final ArrayList mergedList = new ArrayList<>(totalSize);
O lastItem = null;
while (iterator.hasNext()) {
final O item = iterator.next();
if (lastItem == null || !lastItem.equals(item)) {
mergedList.add(item);
}
lastItem = item;
}
mergedList.trimToSize();
return mergedList;
}
/**
* Transforms all elements from input collection with the given transformer
* and adds them to the output collection.
*
* If the input collection or transformer is null, there is no change to the
* output collection.
*
*
* @param the type of object in the input collection
* @param the type of object in the output collection
* @param the type of the output collection
* @param inputCollection the collection to get the input from, may be null
* @param transformer the transformer to use, may be null
* @param outputCollection the collection to output into, may not be null if inputCollection
* and transformer are not null
* @return the output collection with the transformed input added
* @throws NullPointerException if the outputCollection is null and both, inputCollection and
* transformer are not null
*/
public static > R collect(final Iterable extends I> inputCollection,
final Transformer super I, ? extends O> transformer, final R outputCollection) {
if (inputCollection != null) {
return collect(inputCollection.iterator(), transformer, outputCollection);
}
return outputCollection;
}
/**
* Returns a new Collection containing all elements of the input collection
* transformed by the given transformer.
*
* If the input collection or transformer is null, the result is an empty list.
*
*
* @param the type of object in the input collection
* @param the type of object in the output collection
* @param inputCollection the collection to get the input from, may not be null
* @param transformer the transformer to use, may be null
* @return the transformed result (new list)
* @throws NullPointerException if the outputCollection is null and both, inputCollection and
* transformer are not null
*/
public static Collection collect(final Iterable inputCollection,
final Transformer super I, ? extends O> transformer) {
int size = 0;
if (null != inputCollection) {
size = inputCollection instanceof Collection> ? ((Collection>) inputCollection).size() : 0;
}
final Collection answer = size == 0 ? new ArrayList<>() : new ArrayList<>(size);
return collect(inputCollection, transformer, answer);
}
/**
* Transforms all elements from the input iterator with the given transformer
* and adds them to the output collection.
*
* If the input iterator or transformer is null, there is no change to the
* output collection.
*
*
* @param the type of object in the input collection
* @param the type of object in the output collection
* @param the type of the output collection
* @param inputIterator the iterator to get the input from, may be null
* @param transformer the transformer to use, may be null
* @param outputCollection the collection to output into, may not be null if inputIterator
* and transformer are not null
* @return the outputCollection with the transformed input added
* @throws NullPointerException if the output collection is null and both, inputIterator and
* transformer are not null
*/
public static > R collect(final Iterator extends I> inputIterator,
final Transformer super I, ? extends O> transformer, final R outputCollection) {
if (inputIterator != null && transformer != null) {
while (inputIterator.hasNext()) {
final I item = inputIterator.next();
final O value = transformer.apply(item);
outputCollection.add(value);
}
}
return outputCollection;
}
/**
* Transforms all elements from the input iterator with the given transformer
* and adds them to the output collection.
*
* If the input iterator or transformer is null, the result is an empty list.
*
*
* @param the type of object in the input collection
* @param the type of object in the output collection
* @param inputIterator the iterator to get the input from, may be null
* @param transformer the transformer to use, may be null
* @return the transformed result (new list)
*/
public static Collection collect(final Iterator inputIterator,
final Transformer super I, ? extends O> transformer) {
return collect(inputIterator, transformer, new ArrayList<>());
}
/**
* Returns {@code true} iff all elements of {@code coll2} are also contained
* in {@code coll1}. The cardinality of values in {@code coll2} is not taken into account,
* which is the same behavior as {@link Collection#containsAll(Collection)}.
*
* In other words, this method returns {@code true} iff the
* {@link #intersection} of coll1 and coll2 has the same cardinality as
* the set of unique values from {@code coll2}. In case {@code coll2} is empty, {@code true}
* will be returned.
*
*
* This method is intended as a replacement for {@link Collection#containsAll(Collection)}
* with a guaranteed runtime complexity of {@code O(n + m)}. Depending on the type of
* {@link Collection} provided, this method will be much faster than calling
* {@link Collection#containsAll(Collection)} instead, though this will come at the
* cost of an additional space complexity O(n).
*
*
* @param coll1 the first collection, must not be null
* @param coll2 the second collection, must not be null
* @return {@code true} iff the intersection of the collections has the same cardinality
* as the set of unique elements from the second collection
* @throws NullPointerException if coll1 or coll2 is null
* @since 4.0
*/
public static boolean containsAll(final Collection> coll1, final Collection> coll2) {
Objects.requireNonNull(coll1, "coll1");
Objects.requireNonNull(coll2, "coll2");
if (coll2.isEmpty()) {
return true;
}
final Set