Apache Commons Collections

Language: Java

Utilities/Collections

Commons Collections was developed to provide powerful, reusable collection utilities beyond the standard Java Collections Framework. It simplifies tasks such as grouping, counting, bidirectional mapping, transforming, and filtering collections. It is widely used in enterprise Java applications, open-source projects, and frameworks that need enhanced collection handling.

Apache Commons Collections extends the Java Collections Framework with additional interfaces, implementations, and utilities for manipulating and transforming collections. It includes features like Bag, MultiMap, BidiMap, and advanced iterators.

Installation

maven: Add dependency in pom.xml: <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.4</version> </dependency>
gradle: Add dependency in build.gradle: implementation 'org.apache.commons:commons-collections4:4.4'

Usage

Commons Collections provides enhanced collection types like Bag, MultiMap, BidiMap, and utilities for transforming, filtering, and decorating collections. It also offers specialized iterators and predicates for collection manipulation.

Bag example

import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.bag.HashBag;

Bag<String> bag = new HashBag<>();
bag.add("apple", 3);
bag.add("banana");
System.out.println(bag.getCount("apple")); // 3

A Bag counts the occurrences of each element in the collection.

MultiMap example

import org.apache.commons.collections4.MultiMap;
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;

MultiMap<String, String> multiMap = new ArrayListValuedHashMap<>();
multiMap.put("fruit", "apple");
multiMap.put("fruit", "banana");
System.out.println(multiMap.get("fruit"));

Stores multiple values for a single key.

BidiMap example

import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.bidimap.HashBidiMap;

BidiMap<Integer, String> bidi = new HashBidiMap<>();
bidi.put(1, "one");
bidi.put(2, "two");
System.out.println(bidi.getKey("two")); // 2

Allows bidirectional lookup between keys and values.

Transforming collections

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Transformer;

Collection<String> input = Arrays.asList("a", "bb", "ccc");
Collection<String> output = CollectionUtils.collect(input, (Transformer<String, String>) String::toUpperCase);
System.out.println(output);

Transforms all elements in a collection using a function.

Filtering collections

import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.CollectionUtils;

Collection<String> input = Arrays.asList("apple", "banana", "cherry");
Collection<String> result = CollectionUtils.select(input, (Predicate<String>) s -> s.startsWith("a"));
System.out.println(result);

Selects elements from a collection based on a predicate.

LazyList example

import org.apache.commons.collections4.list.LazyList;
import org.apache.commons.collections4.FactoryUtils;
import java.util.ArrayList;

List<String> lazy = LazyList.lazyList(new ArrayList<>(), FactoryUtils.constantFactory("default"));
lazy.add(0, "first");
lazy.add(2, null);
System.out.println(lazy);

Creates a list that generates default elements lazily when accessed.

Error Handling

NullPointerException: Ensure collections are initialized and predicates are not null.
UnsupportedOperationException: Occurs when modifying immutable collections. Use modifiable variants or decorators.

Best Practices

Use Bag for counting occurrences instead of manual maps.

Use MultiMap for key-to-multiple-values mappings.

Use BidiMap for two-way lookup between keys and values.

Use CollectionUtils for transformations, filtering, and null-safe operations.

Avoid overusing legacy iterators when Java 8 streams provide equivalent functionality.