The Apache Commons Collections package contains types that extend and augment the Java Collections Framework
npx @tessl/cli install tessl/maven-org-apache-commons--commons-collections4@4.5.00
# Apache Commons Collections 4
1
2
Apache Commons Collections 4 is a comprehensive Java library that extends and enhances the Java Collections Framework with powerful data structures, algorithms, and utilities. It provides advanced collection types, functional programming support, and extensive utility methods for working with collections.
3
4
## Overview
5
6
Apache Commons Collections 4 extends the Java Collections Framework by providing:
7
8
- **Advanced Collection Types**: Bags (counting collections), bidirectional maps, multi-valued maps, tries, and specialized queues
9
- **Functional Programming**: Predicates, transformers, closures, and factories for collection processing
10
- **Collection Decorators**: Thread-safe, unmodifiable, predicated, and transformed collection wrappers
11
- **Utility Classes**: Extensive static utility methods for common collection operations
12
- **Type Safety**: Full generic type support throughout the library
13
- **Performance**: Optimized implementations with various performance characteristics
14
15
The library is organized into 19 packages covering core collection types, specialized data structures, functional programming utilities, and comprehensive helper classes.
16
17
## Package Information
18
19
- **Package Name**: commons-collections4
20
- **Package Type**: maven
21
- **Language**: Java
22
- **Installation**: Add Maven dependency to your `pom.xml`:
23
24
```xml
25
<dependency>
26
<groupId>org.apache.commons</groupId>
27
<artifactId>commons-collections4</artifactId>
28
<version>4.5.0</version>
29
</dependency>
30
```
31
32
## Core Imports
33
34
```java { .api }
35
// Core interfaces and utilities
36
import org.apache.commons.collections4.*;
37
38
// Bag collections
39
import org.apache.commons.collections4.Bag;
40
import org.apache.commons.collections4.bag.HashBag;
41
import org.apache.commons.collections4.bag.TreeBag;
42
43
// Bidirectional maps
44
import org.apache.commons.collections4.BidiMap;
45
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
46
import org.apache.commons.collections4.bidimap.TreeBidiMap;
47
48
// Multi-valued maps
49
import org.apache.commons.collections4.MultiValuedMap;
50
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
51
import org.apache.commons.collections4.multimap.HashSetValuedHashMap;
52
53
// Functional interfaces
54
import org.apache.commons.collections4.Predicate;
55
import org.apache.commons.collections4.Transformer;
56
import org.apache.commons.collections4.Closure;
57
import org.apache.commons.collections4.Factory;
58
59
// Utility classes
60
import org.apache.commons.collections4.CollectionUtils;
61
import org.apache.commons.collections4.MapUtils;
62
import org.apache.commons.collections4.ListUtils;
63
import org.apache.commons.collections4.SetUtils;
64
```
65
66
## Basic Usage
67
68
### Working with Bags (Counting Collections)
69
```java { .api }
70
import org.apache.commons.collections4.Bag;
71
import org.apache.commons.collections4.bag.HashBag;
72
73
// Create a bag to count occurrences
74
Bag<String> bag = new HashBag<>();
75
bag.add("apple", 3);
76
bag.add("banana", 2);
77
bag.add("apple"); // Now apple has count of 4
78
79
// Get counts
80
int appleCount = bag.getCount("apple"); // Returns 4
81
int totalItems = bag.size(); // Returns 6 (3+2+1)
82
int uniqueItems = bag.uniqueSet().size(); // Returns 2
83
84
// Check contents
85
boolean hasApple = bag.contains("apple");
86
boolean hasPear = bag.contains("pear"); // false
87
```
88
89
### Bidirectional Maps
90
```java { .api }
91
import org.apache.commons.collections4.BidiMap;
92
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
93
94
// Create bidirectional map
95
BidiMap<String, Integer> bidiMap = new DualHashBidiMap<>();
96
bidiMap.put("one", 1);
97
bidiMap.put("two", 2);
98
bidiMap.put("three", 3);
99
100
// Lookup by key (normal map operation)
101
Integer value = bidiMap.get("two"); // Returns 2
102
103
// Lookup by value (reverse lookup)
104
String key = bidiMap.getKey(2); // Returns "two"
105
106
// Get inverse view
107
BidiMap<Integer, String> inverseMap = bidiMap.inverseBidiMap();
108
String keyFromInverse = inverseMap.get(3); // Returns "three"
109
```
110
111
### Multi-Valued Maps
112
```java { .api }
113
import org.apache.commons.collections4.MultiValuedMap;
114
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
115
import java.util.Collection;
116
117
// Create multi-valued map
118
MultiValuedMap<String, String> multiMap = new ArrayListValuedHashMap<>();
119
multiMap.put("colors", "red");
120
multiMap.put("colors", "green");
121
multiMap.put("colors", "blue");
122
multiMap.put("animals", "cat");
123
multiMap.put("animals", "dog");
124
125
// Get all values for a key
126
Collection<String> colors = multiMap.get("colors"); // [red, green, blue]
127
128
// Check size
129
int totalMappings = multiMap.size(); // Returns 5
130
int uniqueKeys = multiMap.keySet().size(); // Returns 2
131
132
// Remove specific mapping
133
boolean removed = multiMap.removeMapping("colors", "red");
134
```
135
136
### Collection Utilities
137
```java { .api }
138
import org.apache.commons.collections4.CollectionUtils;
139
import org.apache.commons.collections4.Predicate;
140
import java.util.List;
141
import java.util.Arrays;
142
import java.util.Collection;
143
144
List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5);
145
List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8);
146
147
// Set operations
148
Collection<Integer> union = CollectionUtils.union(list1, list2); // [1,2,3,4,5,6,7,8]
149
Collection<Integer> intersection = CollectionUtils.intersection(list1, list2); // [4,5]
150
Collection<Integer> difference = CollectionUtils.subtract(list1, list2); // [1,2,3]
151
152
// Filtering with predicates
153
Predicate<Integer> evenPredicate = n -> n % 2 == 0;
154
Collection<Integer> evenNumbers = CollectionUtils.select(list1, evenPredicate); // [2,4]
155
156
// Null-safe operations
157
boolean isEmpty = CollectionUtils.isEmpty(null); // true
158
boolean isNotEmpty = CollectionUtils.isNotEmpty(list1); // true
159
```
160
161
### Functional Programming with Predicates and Transformers
162
```java { .api }
163
import org.apache.commons.collections4.Predicate;
164
import org.apache.commons.collections4.Transformer;
165
import org.apache.commons.collections4.CollectionUtils;
166
import java.util.List;
167
import java.util.Arrays;
168
import java.util.Collection;
169
170
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
171
172
// Create predicates
173
Predicate<String> longNamePredicate = name -> name.length() > 4;
174
Predicate<String> startsWithC = name -> name.startsWith("C");
175
176
// Create transformer
177
Transformer<String, String> upperCaseTransformer = String::toUpperCase;
178
179
// Apply filtering
180
Collection<String> longNames = CollectionUtils.select(names, longNamePredicate); // [Alice, Charlie]
181
182
// Apply transformation
183
Collection<String> upperCaseNames = CollectionUtils.collect(names, upperCaseTransformer); // [ALICE, BOB, CHARLIE, DAVID]
184
185
// Chain operations
186
Collection<String> longUpperCaseNames = CollectionUtils.collect(
187
CollectionUtils.select(names, longNamePredicate),
188
upperCaseTransformer
189
); // [ALICE, CHARLIE]
190
```
191
192
### Fluent Interface
193
```java { .api }
194
import org.apache.commons.collections4.FluentIterable;
195
import java.util.List;
196
import java.util.Arrays;
197
198
List<String> words = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");
199
200
// Fluent chain operations
201
List<String> result = FluentIterable.of(words)
202
.filter(word -> word.length() > 4) // Keep words longer than 4 chars
203
.transform(String::toUpperCase) // Transform to uppercase
204
.limit(2) // Take first 2 results
205
.toList(); // Convert to list
206
// Result: [APPLE, BANANA]
207
208
// Check conditions
209
boolean allLong = FluentIterable.of(words)
210
.allMatch(word -> word.length() > 2); // true
211
212
boolean anyStartsWithA = FluentIterable.of(words)
213
.anyMatch(word -> word.startsWith("a")); // true
214
```
215
216
## Architecture Overview
217
218
Apache Commons Collections 4 follows several key design patterns:
219
220
### 1. Decorator Pattern
221
Collections can be wrapped with decorators that add functionality:
222
223
```java { .api }
224
import org.apache.commons.collections4.list.PredicatedList;
225
import org.apache.commons.collections4.list.SynchronizedList;
226
import org.apache.commons.collections4.list.UnmodifiableList;
227
import java.util.List;
228
import java.util.ArrayList;
229
230
List<String> baseList = new ArrayList<>();
231
232
// Add predicate validation - only allows non-null strings
233
List<String> predicatedList = PredicatedList.predicatedList(baseList, Objects::nonNull);
234
235
// Add thread safety
236
List<String> synchronizedList = SynchronizedList.synchronizedList(predicatedList);
237
238
// Make unmodifiable
239
List<String> unmodifiableList = UnmodifiableList.unmodifiableList(synchronizedList);
240
```
241
242
### 2. Factory Pattern
243
Utility classes provide factory methods for creating enhanced collections:
244
245
```java { .api }
246
import org.apache.commons.collections4.BagUtils;
247
import org.apache.commons.collections4.MapUtils;
248
import org.apache.commons.collections4.bag.HashBag;
249
import java.util.Map;
250
import java.util.HashMap;
251
252
// Create synchronized collections
253
Bag<String> synchronizedBag = BagUtils.synchronizedBag(new HashBag<>());
254
255
// Create lazy maps (values created on first access)
256
Map<String, List<String>> lazyMap = MapUtils.lazyMap(
257
new HashMap<>(),
258
() -> new ArrayList<>()
259
);
260
```
261
262
### 3. Template Method Pattern
263
Abstract base classes provide common functionality while allowing customization:
264
265
- `AbstractMapBag` - Base for bag implementations
266
- `AbstractBidiMap` - Base for bidirectional map implementations
267
- `AbstractMultiValuedMap` - Base for multi-valued map implementations
268
269
### 4. Strategy Pattern
270
Functional interfaces allow pluggable behavior:
271
272
- `Predicate<T>` - Testing strategy
273
- `Transformer<T, R>` - Transformation strategy
274
- `Closure<T>` - Action strategy
275
- `Factory<T>` - Creation strategy
276
277
## Key Capability Areas
278
279
### [Bags and Counting Collections](bags.md)
280
Collections that track element occurrence counts, useful for frequency analysis and statistical operations.
281
282
### [Bidirectional Maps](bidimaps.md)
283
Maps supporting efficient bidirectional lookup between keys and values with 1:1 relationships.
284
285
### [Multi-Valued Maps](multimaps.md)
286
Maps that associate multiple values with each key, supporting both List and Set semantics.
287
288
### [Advanced Collections](advanced-collections.md)
289
Specialized collections including tries, bloom filters, queues, and iterators for specific use cases.
290
291
### [Functional Programming](functional-programming.md)
292
Comprehensive support for functional-style programming with predicates, transformers, closures, and factories.
293
294
### [Collection Utilities](collection-utilities.md)
295
Extensive utility methods for collection operations, transformations, and manipulations.
296
297
## Type Safety and Generics
298
299
All classes and interfaces in Apache Commons Collections 4 are fully generic-enabled:
300
301
```java { .api }
302
// Type-safe bag operations
303
Bag<Person> people = new HashBag<>();
304
people.add(new Person("Alice"));
305
int count = people.getCount(new Person("Alice"));
306
307
// Type-safe transformations
308
Transformer<Person, String> nameExtractor = Person::getName;
309
Collection<String> names = CollectionUtils.collect(people, nameExtractor);
310
311
// Type-safe predicates
312
Predicate<Person> adultPredicate = person -> person.getAge() >= 18;
313
Collection<Person> adults = CollectionUtils.select(people, adultPredicate);
314
```
315
316
## Thread Safety Considerations
317
318
Commons Collections provides thread-safe wrappers for all collection types:
319
320
```java { .api }
321
// Thread-safe collections
322
Map<String, Object> safeMap = MapUtils.synchronizedMap(new HashMap<>());
323
List<String> safeList = ListUtils.synchronizedList(new ArrayList<>());
324
Set<String> safeSet = SetUtils.synchronizedSet(new HashSet<>());
325
Bag<String> safeBag = BagUtils.synchronizedBag(new HashBag<>());
326
327
// Note: Iteration still requires external synchronization
328
synchronized(safeList) {
329
for(String item : safeList) {
330
// Safe iteration
331
}
332
}
333
```
334
335
## Performance Characteristics
336
337
Different implementations provide different performance characteristics:
338
339
- **HashBag/HashMultiSet**: O(1) average case operations
340
- **TreeBag**: O(log n) operations with sorted order
341
- **LinkedMap**: O(1) operations with insertion order
342
- **LRUMap**: O(1) operations with automatic eviction
343
- **PatriciaTrie**: O(k) operations where k is key length
344
345
Choose implementations based on your specific requirements for speed, memory usage, and ordering guarantees.
346
347
## Migration from Collections 3.x
348
349
Apache Commons Collections 4 provides significant improvements over version 3.x:
350
351
1. **Full Generics Support**: No more raw types or casting
352
2. **Java 8+ Features**: Integration with streams and functional interfaces
353
3. **Improved API**: More consistent method names and better separation of concerns
354
4. **New Collection Types**: MultiValuedMap, enhanced Trie implementations
355
5. **Better Performance**: Optimized implementations and algorithms
356
357
For migration guidance, see the official migration documentation and RELEASE-NOTES.txt in the source distribution.