Guide to Apache Commons Collections in Java

Introduction to Apache Commons Collections

Apache Commons Collections is a library that provides additional data structures and utilities to complement the Java Collections Framework. This guide will cover installation, basic usage, advanced features, and various use cases of Apache Commons Collections using the latest version.

Installation

Adding Apache Commons Collections to Your Project

To use Apache Commons Collections, add the following dependency to your pom.xml if you're using Maven:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.4</version> <!-- or the latest version -->
</dependency>

For Gradle:

implementation 'org.apache.commons:commons-collections4:4.4'

Basic Usage

BidiMap

A BidiMap is a map that allows bidirectional lookup between keys and values.

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

public class BidiMapExample {
    public static void main(String[] args) {
        BidiMap<Integer, String> bidiMap = new TreeBidiMap<>();
        bidiMap.put(1, "Amit");
        bidiMap.put(2, "Priya");
        bidiMap.put(3, "Vikas");

        System.out.println("Original Map: " + bidiMap);
        System.out.println("Value for key 1: " + bidiMap.get(1));
        System.out.println("Key for value 'Priya': " + bidiMap.getKey("Priya"));
    }
}

Explanation: This example demonstrates the usage of BidiMap which supports bidirectional lookup. You can retrieve a value by key or a key by value.

Output:

Original Map: {1=Amit, 2=Priya, 3=Vikas}
Value for key 1: Amit
Key for value 'Priya': 2

MultiMap

A MultiMap is a map that allows multiple values for a single key.

import org.apache.commons.collections4.MultiMap;
import org.apache.commons.collections4.map.MultiValueMap;

public class MultiMapExample {
    public static void main(String[] args) {
        MultiMap<String, String> multiMap = new MultiValueMap<>();
        multiMap.put("Amit", "Math");
        multiMap.put("Amit", "Science");
        multiMap.put("Priya", "History");

        System.out.println("MultiMap: " + multiMap);
        System.out.println("Values for key 'Amit': " + multiMap.get("Amit"));
    }
}

Explanation: This example demonstrates the usage of MultiMap which allows multiple values for a single key.

Output:

MultiMap: {Amit=[Math, Science], Priya=[History]}
Values for key 'Amit': [Math, Science]

Bag

A Bag is a collection where elements can occur multiple times.

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

public class BagExample {
    public static void main(String[] args) {
        Bag<String> bag = new HashBag<>();
        bag.add("Amit");
        bag.add("Priya", 2);
        bag.add("Vikas");

        System.out.println("Bag: " + bag);
        System.out.println("Count of 'Priya': " + bag.getCount("Priya"));
    }
}

Explanation: This example demonstrates the usage of Bag which allows elements to occur multiple times and provides a count for each element.

Output:

Bag: [1:Amit,2:Priya,1:Vikas]
Count of 'Priya': 2

CollectionUtils

The CollectionUtils class provides utility methods for collections.

Checking if a Collection is Empty

import org.apache.commons.collections4.CollectionUtils;
import java.util.ArrayList;
import java.util.List;

public class CollectionUtilsExample {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        System.out.println("Is collection empty? " + CollectionUtils.isEmpty(names));

        names.add("Amit");
        System.out.println("Is collection empty? " + CollectionUtils.isEmpty(names));
    }
}

Explanation: This example demonstrates the usage of CollectionUtils.isEmpty to check if a collection is empty.

Output:

Is collection empty? true
Is collection empty? false

Checking if Two Collections Are Equal

import org.apache.commons.collections4.CollectionUtils;
import java.util.Arrays;
import java.util.List;

public class CollectionUtilsEqualsExample {
    public static void main(String[] args) {
        List<String> list1 = Arrays.asList("Amit", "Priya", "Vikas");
        List<String> list2 = Arrays.asList("Amit", "Priya", "Vikas");

        System.out.println("Are collections equal? " + CollectionUtils.isEqualCollection(list1, list2));
    }
}

Explanation: This example demonstrates the usage of CollectionUtils.isEqualCollection to check if two collections are equal.

Output:

Are collections equal? true

Advanced Features

Transforming Collections

You can transform elements in a collection using CollectionUtils.

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Transformer;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class TransformExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Amit", "Priya", "Vikas");
        List<String> transformedNames = CollectionUtils.collect(names, new Transformer<String, String>() {
            @Override
            public String transform(String input) {
                return input.toUpperCase();
            }
        }, new ArrayList<>());

        System.out.println("Transformed Names: " + transformedNames);
    }
}

Explanation: This example demonstrates how to transform a collection using CollectionUtils.collect and a Transformer.

Output:

Transformed Names: [AMIT, PRIYA, VIKAS]

Predicates

Predicates can be used to filter collections.

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import java.util.Arrays;
import java.util.List;

public class PredicateExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Amit", "Priya", "Vikas");

        List<String> filteredNames = CollectionUtils.select(names, new Predicate<String>() {
            @Override
            public boolean evaluate(String input) {
                return input.startsWith("A");
            }
        });

        System.out.println("Filtered Names: " + filteredNames);
    }
}

Explanation: This example demonstrates how to filter a collection using CollectionUtils.select and a Predicate.

Output:

Filtered Names: [Amit]

Using Lazy Collections

LazyCollection creates collections that initialize their elements on demand.

import org.apache.commons.collections4.Factory;
import org.apache.commons.collections4.list.LazyList;
import java.util.List;

public class LazyCollectionExample {
    public static void main(String[] args) {
        Factory<String> factory = new Factory<String>() {
            private int index = 1;
            @Override
            public String create() {
                return "Name " + index++;
            }
        };

        List<String> lazyList = LazyList.lazyList(new ArrayList<>(), factory);

        for (int i = 0; i < 3; i++) {
            lazyList.get(i); // Triggers factory to create elements
        }

        System.out.println("Lazy List: " + lazyList);
    }
}

Explanation: This example demonstrates how to use LazyList to create elements on demand using a Factory.

Output:

Lazy List: [Name 1, Name 2, Name 3]

MultiKey Map

A MultiKeyMap allows multiple keys to be associated with a single value.

import org.apache.commons.collections4.map.MultiKeyMap;

public class MultiKeyMapExample {
    public static void main(String[] args) {
        MultiKeyMap<String, String> multiKeyMap = new MultiKeyMap<>();
        multiKeyMap.put("Amit", "Sharma", "Developer");
        multiKeyMap.put("Priya", "Verma", "Manager");

        System.out.println("Role of Amit Sharma: " + multiKeyMap.get("Amit", "Sharma"));
        System.out.println("Role of Priya Verma: " + multiKeyMap.get("Priya", "Verma"));
    }
}

Explanation: This example demonstrates the usage of MultiKeyMap to associate a value with multiple keys.

Output:

Role of Amit Sharma: Developer
Role of Priya Verma: Manager

Tries

Trie is a prefix tree used to store associative data structures.

import org.apache.commons.collections4.trie.PatriciaTrie;

public class TrieExample {
    public static void main(String[] args) {
        PatriciaTrie<String> trie = new PatriciaTrie<>();
        trie.put("Amit", "Sharma");
        trie.put("Amitabh", "Bachchan");
        trie.put("Amitesh", "Rathore");

        System.out.println("Trie:" + trie.prefixMap("Amit"));
    }
}

Explanation: This example demonstrates the usage of PatriciaTrie to store and retrieve values based on a common prefix.

Output:

Trie: {Amit=Sharma, Amitabh=Bachchan, Amitesh=Rathore}

CollectionUtils Union and Intersection

You can find the union and intersection of collections using CollectionUtils.

Union

import org.apache.commons.collections4.CollectionUtils;
import java.util.Arrays;
import java.util.List;

public class UnionExample {
    public static void main(String[] args) {
        List<String> list1 = Arrays.asList("Amit", "Priya");
        List<String> list2 = Arrays.asList("Priya", "Vikas");

        List<String> union = (List<String>) CollectionUtils.union(list1, list2);
        System.out.println("Union: " + union);
    }
}

Explanation: This example demonstrates how to find the union of two collections using CollectionUtils.union.

Output:

Union: [Amit, Priya, Vikas]

Intersection

import org.apache.commons.collections4.CollectionUtils;
import java.util.Arrays;
import java.util.List;

public class IntersectionExample {
    public static void main(String[] args) {
        List<String> list1 = Arrays.asList("Amit", "Priya");
        List<String> list2 = Arrays.asList("Priya", "Vikas");

        List<String> intersection = (List<String>) CollectionUtils.intersection(list1, list2);
        System.out.println("Intersection: " + intersection);
    }
}

Explanation: This example demonstrates how to find the intersection of two collections using CollectionUtils.intersection.

Output:

Intersection: [Priya]

Conclusion

Apache Commons Collections is a versatile and powerful library that enhances the Java Collections Framework with additional data structures and utilities. This guide covered the basics of using BidiMap, MultiMap, Bag, CollectionUtils, Lazy Collections, MultiKeyMap, Tries, and operations like union and intersection. 

By leveraging Apache Commons Collections, you can simplify and enhance your Java code when working with collections. For more detailed information and advanced features, refer to the official Apache Commons Collections documentation.

Comments