0
# Collection Utilities
1
2
Apache Commons Collections provides extensive utility classes with static methods for common collection operations. These utilities offer null-safe operations, set theory functions, transformations, and decorators for all major collection types.
3
4
## CollectionUtils - Core Collection Operations
5
6
### Basic Operations and Null Safety
7
8
```java { .api }
9
import org.apache.commons.collections4.CollectionUtils;
10
import java.util.List;
11
import java.util.Arrays;
12
import java.util.Collection;
13
import java.util.ArrayList;
14
15
// Null-safe operations
16
boolean isEmpty = CollectionUtils.isEmpty(null); // true
17
boolean isNotEmpty = CollectionUtils.isNotEmpty(null); // false
18
19
List<String> emptyList = new ArrayList<>();
20
boolean empty = CollectionUtils.isEmpty(emptyList); // true
21
22
List<String> items = Arrays.asList("a", "b", "c");
23
boolean notEmpty = CollectionUtils.isNotEmpty(items); // true
24
25
// Safe size operations
26
int size = CollectionUtils.size(null); // 0
27
int actualSize = CollectionUtils.size(items); // 3
28
29
// Safe addition (ignores null elements)
30
Collection<String> collection = new ArrayList<>();
31
CollectionUtils.addIgnoreNull(collection, "item"); // Added
32
CollectionUtils.addIgnoreNull(collection, null); // Ignored
33
34
// Add multiple elements safely
35
String[] elements = {"a", "b", "c"};
36
CollectionUtils.addAll(collection, elements);
37
```
38
39
### Set Theory Operations
40
41
```java { .api }
42
List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5);
43
List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8);
44
45
// Union (all unique elements from both collections)
46
Collection<Integer> union = CollectionUtils.union(list1, list2);
47
// Result: [1, 2, 3, 4, 5, 6, 7, 8]
48
49
// Intersection (common elements)
50
Collection<Integer> intersection = CollectionUtils.intersection(list1, list2);
51
// Result: [4, 5]
52
53
// Disjunction (elements in either collection but not both)
54
Collection<Integer> disjunction = CollectionUtils.disjunction(list1, list2);
55
// Result: [1, 2, 3, 6, 7, 8]
56
57
// Subtract (elements in first collection but not in second)
58
Collection<Integer> difference = CollectionUtils.subtract(list1, list2);
59
// Result: [1, 2, 3]
60
61
// Cardinality (count occurrences of element)
62
List<String> words = Arrays.asList("apple", "banana", "apple", "cherry", "apple");
63
int appleCount = CollectionUtils.cardinality("apple", words); // 3
64
int orangeCount = CollectionUtils.cardinality("orange", words); // 0
65
```
66
67
### Filtering and Selection
68
69
```java { .api }
70
import org.apache.commons.collections4.Predicate;
71
72
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
73
74
// Select elements matching predicate
75
Predicate<Integer> evenPredicate = n -> n % 2 == 0;
76
Collection<Integer> evenNumbers = CollectionUtils.select(numbers, evenPredicate);
77
// Result: [2, 4, 6, 8, 10]
78
79
// Reject elements matching predicate (opposite of select)
80
Collection<Integer> oddNumbers = CollectionUtils.selectRejected(numbers, evenPredicate);
81
// Result: [1, 3, 5, 7, 9]
82
83
// Find first element matching predicate
84
Integer firstEven = CollectionUtils.find(numbers, evenPredicate); // 2
85
86
// Check if any element matches predicate
87
boolean hasEven = CollectionUtils.exists(numbers, evenPredicate); // true
88
89
// Count matching elements
90
int evenCount = CollectionUtils.countMatches(numbers, evenPredicate); // 5
91
92
// Complex predicates
93
Predicate<Integer> largeEven = n -> n % 2 == 0 && n > 5;
94
Collection<Integer> largeEvens = CollectionUtils.select(numbers, largeEven);
95
// Result: [6, 8, 10]
96
```
97
98
### Transformations
99
100
```java { .api }
101
import org.apache.commons.collections4.Transformer;
102
103
List<String> words = Arrays.asList("hello", "world", "java", "collections");
104
105
// Transform collection elements
106
Transformer<String, String> upperCase = String::toUpperCase;
107
Collection<String> upperWords = CollectionUtils.collect(words, upperCase);
108
// Result: ["HELLO", "WORLD", "JAVA", "COLLECTIONS"]
109
110
Transformer<String, Integer> stringLength = String::length;
111
Collection<Integer> wordLengths = CollectionUtils.collect(words, stringLength);
112
// Result: [5, 5, 4, 11]
113
114
// Transform and add to existing collection
115
Collection<String> result = new ArrayList<>();
116
CollectionUtils.collect(words, upperCase, result);
117
// result now contains uppercase words
118
119
// Chain transformations
120
Transformer<String, String> trimUpper = s -> s.trim().toUpperCase();
121
Collection<String> processed = CollectionUtils.collect(
122
Arrays.asList(" hello ", " world ", " java "),
123
trimUpper
124
);
125
// Result: ["HELLO", "WORLD", "JAVA"]
126
```
127
128
### Equality and Comparison
129
130
```java { .api }
131
List<String> list1 = Arrays.asList("a", "b", "c");
132
List<String> list2 = Arrays.asList("c", "b", "a");
133
List<String> list3 = Arrays.asList("a", "b", "c");
134
135
// Equal collections (same elements, same cardinalities, order doesn't matter)
136
boolean equal1 = CollectionUtils.isEqualCollection(list1, list2); // true
137
boolean equal2 = CollectionUtils.isEqualCollection(list1, list3); // true
138
139
// Check if collection is a sub-collection
140
List<String> subset = Arrays.asList("a", "b");
141
boolean isSubCollection = CollectionUtils.isSubCollection(subset, list1); // true
142
143
// Check if collection is a proper sub-collection (subset but not equal)
144
boolean isProperSubCollection = CollectionUtils.isProperSubCollection(subset, list1); // true
145
boolean isProperSelf = CollectionUtils.isProperSubCollection(list1, list1); // false
146
```
147
148
## ListUtils - List-Specific Operations
149
150
### List Set Operations
151
152
```java { .api }
153
import org.apache.commons.collections4.ListUtils;
154
155
List<String> list1 = Arrays.asList("a", "b", "c", "d");
156
List<String> list2 = Arrays.asList("c", "d", "e", "f");
157
158
// Union preserving order and duplicates
159
List<String> union = ListUtils.union(list1, list2);
160
// Result: ["a", "b", "c", "d", "c", "d", "e", "f"]
161
162
// Intersection preserving order
163
List<String> intersection = ListUtils.intersection(list1, list2);
164
// Result: ["c", "d"]
165
166
// Subtract (elements in first but not in second)
167
List<String> subtract = ListUtils.subtract(list1, list2);
168
// Result: ["a", "b"]
169
170
// Sum (concatenation)
171
List<String> sum = ListUtils.sum(list1, list2);
172
// Result: ["a", "b", "c", "d", "c", "d", "e", "f"]
173
```
174
175
### List Equality and Manipulation
176
177
```java { .api }
178
List<Integer> list1 = Arrays.asList(1, 2, 3, 4);
179
List<Integer> list2 = Arrays.asList(1, 2, 3, 4);
180
List<Integer> list3 = Arrays.asList(4, 3, 2, 1);
181
182
// Order-sensitive equality (unlike CollectionUtils.isEqualCollection)
183
boolean equalLists = ListUtils.isEqualList(list1, list2); // true
184
boolean differentOrder = ListUtils.isEqualList(list1, list3); // false
185
186
// Hash code for lists
187
int hashCode1 = ListUtils.hashCodeForList(list1);
188
int hashCode2 = ListUtils.hashCodeForList(list2); // Same as hashCode1
189
190
// Retain elements (intersection that modifies original collection concept)
191
List<Integer> toRetain = Arrays.asList(2, 3, 5, 6);
192
List<Integer> retained = ListUtils.retainAll(list1, toRetain);
193
// Result: [2, 3] (elements from list1 that are also in toRetain)
194
195
// Remove elements
196
List<Integer> toRemove = Arrays.asList(2, 4);
197
List<Integer> remaining = ListUtils.removeAll(list1, toRemove);
198
// Result: [1, 3] (elements from list1 not in toRemove)
199
```
200
201
### List Partitioning
202
203
```java { .api }
204
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
205
206
// Partition into sublists of specified size
207
List<List<Integer>> partitions = ListUtils.partition(numbers, 3);
208
// Result: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
209
210
// Process partitions
211
for (List<Integer> partition : partitions) {
212
System.out.println("Partition sum: " + partition.stream().mapToInt(Integer::intValue).sum());
213
}
214
215
// Useful for batch processing
216
List<String> largeList = generateLargeList(); // Imagine 10,000 items
217
List<List<String>> batches = ListUtils.partition(largeList, 100);
218
for (List<String> batch : batches) {
219
processBatch(batch); // Process 100 items at a time
220
}
221
```
222
223
### List Decorators
224
225
```java { .api }
226
import java.util.ArrayList;
227
228
List<String> baseList = new ArrayList<>();
229
baseList.addAll(Arrays.asList("a", "b", "c"));
230
231
// Synchronized list
232
List<String> syncList = ListUtils.synchronizedList(baseList);
233
234
// Unmodifiable list
235
List<String> readOnlyList = ListUtils.unmodifiableList(baseList);
236
237
// Predicated list (validates additions)
238
Predicate<String> notEmpty = s -> s != null && !s.trim().isEmpty();
239
List<String> validatedList = ListUtils.predicatedList(new ArrayList<>(), notEmpty);
240
validatedList.add("valid"); // OK
241
// validatedList.add(""); // Would throw IllegalArgumentException
242
243
// Transformed list (transforms elements on addition)
244
Transformer<String, String> upperCase = String::toUpperCase;
245
List<String> transformedList = ListUtils.transformedList(new ArrayList<>(), upperCase);
246
transformedList.add("hello"); // Stored as "HELLO"
247
248
// Lazy list (creates elements on demand)
249
Factory<String> defaultFactory = () -> "default";
250
List<String> lazyList = ListUtils.lazyList(new ArrayList<>(), defaultFactory);
251
String item = lazyList.get(5); // Creates elements 0-5 with "default" value
252
253
// Fixed size list (prevents size changes)
254
List<String> fixedList = ListUtils.fixedSizeList(new ArrayList<>(Arrays.asList("a", "b", "c")));
255
fixedList.set(0, "changed"); // OK - modification allowed
256
// fixedList.add("new"); // Would throw UnsupportedOperationException
257
```
258
259
## SetUtils - Set-Specific Operations
260
261
### Set Operations with Views
262
263
```java { .api }
264
import org.apache.commons.collections4.SetUtils;
265
import java.util.Set;
266
import java.util.HashSet;
267
268
Set<String> set1 = new HashSet<>(Arrays.asList("a", "b", "c", "d"));
269
Set<String> set2 = new HashSet<>(Arrays.asList("c", "d", "e", "f"));
270
271
// Immutable set views (don't copy data, just provide views)
272
SetUtils.SetView<String> unionView = SetUtils.union(set1, set2);
273
// View contains: ["a", "b", "c", "d", "e", "f"]
274
275
SetUtils.SetView<String> intersectionView = SetUtils.intersection(set1, set2);
276
// View contains: ["c", "d"]
277
278
SetUtils.SetView<String> differenceView = SetUtils.difference(set1, set2);
279
// View contains: ["a", "b"] (in set1 but not set2)
280
281
SetUtils.SetView<String> disjunctionView = SetUtils.disjunction(set1, set2);
282
// View contains: ["a", "b", "e", "f"] (in either set but not both)
283
284
// Views are live - changes to original sets are reflected
285
set1.add("x");
286
System.out.println(unionView.contains("x")); // true
287
288
// Convert view to concrete set when needed
289
Set<String> concreteUnion = new HashSet<>(unionView);
290
```
291
292
### Set Equality and Validation
293
294
```java { .api }
295
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3));
296
Set<Integer> set2 = new HashSet<>(Arrays.asList(3, 2, 1)); // Different order
297
List<Integer> list = Arrays.asList(1, 2, 3, 2); // With duplicate
298
299
// Set equality (order doesn't matter)
300
boolean equal = SetUtils.isEqualSet(set1, set2); // true
301
302
// Check if collection represents a valid set (no duplicates)
303
boolean validSet1 = SetUtils.isEqualSet(set1, list); // false (list has duplicate)
304
305
// Hash code for sets
306
int hashCode = SetUtils.hashCodeForSet(set1);
307
```
308
309
### Set Decorators
310
311
```java { .api }
312
Set<String> baseSet = new HashSet<>();
313
314
// Synchronized set
315
Set<String> syncSet = SetUtils.synchronizedSet(baseSet);
316
317
// Unmodifiable set
318
Set<String> readOnlySet = SetUtils.unmodifiableSet(new HashSet<>(Arrays.asList("a", "b", "c")));
319
320
// Predicated set
321
Predicate<String> notNull = Objects::nonNull;
322
Set<String> validatedSet = SetUtils.predicatedSet(new HashSet<>(), notNull);
323
324
// Transformed set
325
Transformer<String, String> lowerCase = String::toLowerCase;
326
Set<String> transformedSet = SetUtils.transformedSet(new HashSet<>(), lowerCase);
327
transformedSet.add("HELLO"); // Stored as "hello"
328
329
// Empty immutable set
330
Set<String> empty = SetUtils.emptySet(); // Singleton empty set
331
```
332
333
## MapUtils - Map Operations
334
335
### Basic Map Operations
336
337
```java { .api }
338
import org.apache.commons.collections4.MapUtils;
339
import java.util.Map;
340
import java.util.HashMap;
341
342
Map<String, Integer> map = new HashMap<>();
343
map.put("apple", 5);
344
map.put("banana", 3);
345
map.put("cherry", 8);
346
347
// Null-safe operations
348
boolean isEmpty = MapUtils.isEmpty(null); // true
349
boolean isNotEmpty = MapUtils.isNotEmpty(map); // true
350
351
// Safe value retrieval with defaults
352
Integer value = MapUtils.getInteger(map, "apple"); // 5
353
Integer missing = MapUtils.getInteger(map, "orange"); // null
354
Integer withDefault = MapUtils.getInteger(map, "orange", 0); // 0
355
356
// Type-safe getters
357
String stringValue = MapUtils.getString(map, "apple"); // "5" (converted)
358
Boolean boolValue = MapUtils.getBoolean(map, "apple"); // true (5 -> true)
359
Double doubleValue = MapUtils.getDouble(map, "apple"); // 5.0
360
361
// Safe addition (ignores if key or value is problematic)
362
MapUtils.safeAddToMap(map, "date", new Date());
363
```
364
365
### Map Inversion and Debugging
366
367
```java { .api }
368
Map<String, Integer> original = Map.of("a", 1, "b", 2, "c", 3);
369
370
// Invert key-value pairs (assumes values are unique)
371
Map<Integer, String> inverted = MapUtils.invertMap(original);
372
// Result: {1="a", 2="b", 3="c"}
373
374
// Debug printing
375
MapUtils.debugPrint(System.out, "Original Map", original);
376
// Prints formatted key-value pairs for debugging
377
378
MapUtils.verbosePrint(System.out, "Detailed Map", original);
379
// Prints with more detailed formatting
380
```
381
382
### Map Decorators
383
384
```java { .api }
385
Map<String, String> baseMap = new HashMap<>();
386
387
// Synchronized map
388
Map<String, String> syncMap = MapUtils.synchronizedMap(baseMap);
389
390
// Unmodifiable map
391
Map<String, String> readOnlyMap = MapUtils.unmodifiableMap(
392
Map.of("key1", "value1", "key2", "value2")
393
);
394
395
// Predicated map (validates keys and values)
396
Predicate<String> notEmpty = s -> s != null && !s.trim().isEmpty();
397
IterableMap<String, String> validatedMap = MapUtils.predicatedMap(
398
new HashMap<>(),
399
notEmpty, // Key predicate
400
notEmpty // Value predicate
401
);
402
403
// Transformed map
404
Transformer<String, String> keyUpper = String::toUpperCase;
405
Transformer<String, String> valueUpper = String::toUpperCase;
406
IterableMap<String, String> transformedMap = MapUtils.transformedMap(
407
new HashMap<>(),
408
keyUpper, // Key transformer
409
valueUpper // Value transformer
410
);
411
412
// Lazy map (creates values on first access)
413
Factory<List<String>> listFactory = ArrayList::new;
414
IterableMap<String, List<String>> lazyMap = MapUtils.lazyMap(new HashMap<>(), listFactory);
415
lazyMap.get("key1").add("value"); // Creates ArrayList automatically
416
417
// Fixed size map (prevents adding new entries)
418
IterableMap<String, String> fixedMap = MapUtils.fixedSizeMap(
419
new HashMap<>(Map.of("existing", "value"))
420
);
421
```
422
423
## Advanced Utility Patterns
424
425
### Fluent Processing Chains
426
427
```java { .api }
428
import org.apache.commons.collections4.FluentIterable;
429
430
List<String> input = Arrays.asList(" hello ", "", "WORLD", " java ", null, "collections");
431
432
// Chain operations fluently
433
List<String> processed = FluentIterable.of(input)
434
.filter(Objects::nonNull) // Remove nulls
435
.filter(s -> !s.trim().isEmpty()) // Remove empty strings
436
.transform(String::trim) // Trim whitespace
437
.transform(String::toLowerCase) // Convert to lowercase
438
.filter(s -> s.length() > 3) // Keep only longer words
439
.toList();
440
// Result: ["hello", "world", "java", "collections"]
441
442
// Check conditions on entire collection
443
boolean allLongWords = FluentIterable.of(processed)
444
.allMatch(s -> s.length() > 2); // true
445
446
boolean anyStartsWithJ = FluentIterable.of(processed)
447
.anyMatch(s -> s.startsWith("j")); // true
448
449
// Limit and skip operations
450
List<String> limited = FluentIterable.of(processed)
451
.skip(1) // Skip first element
452
.limit(2) // Take next 2 elements
453
.toList();
454
// Result: ["world", "java"]
455
```
456
457
### Collection Pipeline Factory
458
459
```java { .api }
460
public class CollectionPipeline {
461
public static <T> Builder<T> from(Collection<T> source) {
462
return new Builder<>(source);
463
}
464
465
public static class Builder<T> {
466
private Collection<T> current;
467
468
public Builder(Collection<T> source) {
469
this.current = new ArrayList<>(source);
470
}
471
472
public Builder<T> filter(Predicate<T> predicate) {
473
current = CollectionUtils.select(current, predicate);
474
return this;
475
}
476
477
public <R> Builder<R> transform(Transformer<T, R> transformer) {
478
Collection<R> transformed = CollectionUtils.collect(current, transformer);
479
return new Builder<>(transformed);
480
}
481
482
public Builder<T> unique() {
483
current = new ArrayList<>(new LinkedHashSet<>(current));
484
return this;
485
}
486
487
public List<T> toList() {
488
return new ArrayList<>(current);
489
}
490
491
public Set<T> toSet() {
492
return new HashSet<>(current);
493
}
494
}
495
496
// Usage example
497
public static void example() {
498
List<String> words = Arrays.asList("hello", "world", "hello", "java", "world");
499
500
List<String> processed = CollectionPipeline.from(words)
501
.filter(s -> s.length() > 4) // Only words longer than 4 chars
502
.transform(String::toUpperCase) // Convert to uppercase
503
.unique() // Remove duplicates
504
.toList();
505
// Result: ["HELLO", "WORLD"]
506
}
507
}
508
```
509
510
### Null-Safe Collection Operations
511
512
```java { .api }
513
public class SafeCollectionUtils {
514
515
public static <T> Collection<T> safeUnion(Collection<T> a, Collection<T> b) {
516
if (CollectionUtils.isEmpty(a)) return b == null ? Collections.emptyList() : new ArrayList<>(b);
517
if (CollectionUtils.isEmpty(b)) return new ArrayList<>(a);
518
return CollectionUtils.union(a, b);
519
}
520
521
public static <T> boolean safeContains(Collection<T> collection, T item) {
522
return CollectionUtils.isNotEmpty(collection) && collection.contains(item);
523
}
524
525
public static <T> List<T> safeSubList(List<T> list, int fromIndex, int toIndex) {
526
if (CollectionUtils.isEmpty(list)) return Collections.emptyList();
527
int size = list.size();
528
int safeFrom = Math.max(0, Math.min(fromIndex, size));
529
int safeTo = Math.max(safeFrom, Math.min(toIndex, size));
530
return list.subList(safeFrom, safeTo);
531
}
532
533
public static <T> T safeGet(List<T> list, int index, T defaultValue) {
534
if (CollectionUtils.isEmpty(list) || index < 0 || index >= list.size()) {
535
return defaultValue;
536
}
537
return list.get(index);
538
}
539
}
540
```
541
542
### Performance-Optimized Utilities
543
544
```java { .api }
545
public class PerformanceUtils {
546
547
// Efficient membership testing for large collections
548
public static <T> Predicate<T> createMembershipPredicate(Collection<T> collection) {
549
if (CollectionUtils.isEmpty(collection)) {
550
return t -> false;
551
}
552
553
// Use Set for O(1) lookup if not already a Set
554
Set<T> lookupSet = collection instanceof Set
555
? (Set<T>) collection
556
: new HashSet<>(collection);
557
558
return lookupSet::contains;
559
}
560
561
// Batch process large collections to avoid memory issues
562
public static <T> void processBatches(Collection<T> items, int batchSize,
563
Consumer<List<T>> batchProcessor) {
564
if (CollectionUtils.isEmpty(items)) return;
565
566
List<T> itemList = items instanceof List
567
? (List<T>) items
568
: new ArrayList<>(items);
569
570
List<List<T>> batches = ListUtils.partition(itemList, batchSize);
571
batches.forEach(batchProcessor);
572
}
573
574
// Efficient filtering for large collections
575
public static <T> Collection<T> efficientFilter(Collection<T> source, Predicate<T> predicate) {
576
if (CollectionUtils.isEmpty(source)) return Collections.emptyList();
577
578
// Pre-size collection for efficiency
579
Collection<T> result = new ArrayList<>(source.size() / 4); // Assume 25% pass filter
580
581
for (T item : source) {
582
if (predicate.evaluate(item)) {
583
result.add(item);
584
}
585
}
586
587
return result;
588
}
589
}
590
```
591
592
## Best Practices
593
594
### Choosing the Right Utility Method
595
596
```java { .api }
597
// For null safety, always prefer Commons Collections utilities
598
Collection<String> safe = CollectionUtils.emptyIfNull(possiblyNullCollection);
599
int size = CollectionUtils.size(possiblyNullCollection); // Returns 0 if null
600
601
// For performance-critical operations, consider the collection type
602
Set<String> set = new HashSet<>();
603
List<String> list = new ArrayList<>();
604
605
// Fast for Set, slower for List
606
boolean inSet = set.contains("item"); // O(1) average
607
boolean inList = list.contains("item"); // O(n)
608
609
// Use appropriate set operations
610
Collection<String> intersection = CollectionUtils.intersection(set, list); // Efficient
611
```
612
613
### Memory and Performance Considerations
614
615
```java { .api }
616
// Memory-efficient operations
617
List<String> huge = getHugeList(); // 1M items
618
619
// Memory efficient - doesn't create intermediate collections
620
long count = huge.stream().filter(s -> s.startsWith("prefix")).count();
621
622
// Less memory efficient - creates filtered collection
623
Collection<String> filtered = CollectionUtils.select(huge, s -> s.startsWith("prefix"));
624
625
// For repeated operations, create reusable predicates
626
Predicate<String> startsWithPrefix = s -> s.startsWith("prefix");
627
Collection<String> filtered1 = CollectionUtils.select(collection1, startsWithPrefix);
628
Collection<String> filtered2 = CollectionUtils.select(collection2, startsWithPrefix);
629
```
630
631
## IteratorUtils - Iterator Operations
632
633
Comprehensive utilities for working with iterators, providing creation, transformation, and manipulation methods.
634
635
```java { .api }
636
import org.apache.commons.collections4.IteratorUtils;
637
import java.util.Iterator;
638
import java.util.List;
639
import java.util.Arrays;
640
641
List<String> list1 = Arrays.asList("a", "b", "c");
642
List<String> list2 = Arrays.asList("d", "e", "f");
643
644
// Chain multiple iterators
645
Iterator<String> chained = IteratorUtils.chainedIterator(list1.iterator(), list2.iterator());
646
// Iterates through: a, b, c, d, e, f
647
648
// Filter iterator
649
Iterator<String> filtered = IteratorUtils.filteredIterator(list1.iterator(), s -> s.compareTo("b") >= 0);
650
// Iterates through: b, c
651
652
// Transform iterator
653
Iterator<String> transformed = IteratorUtils.transformedIterator(list1.iterator(), String::toUpperCase);
654
// Iterates through: A, B, C
655
656
// Get single element safely
657
String first = IteratorUtils.get(list1.iterator(), 0); // "a"
658
String outOfBounds = IteratorUtils.get(list1.iterator(), 10); // null
659
660
// Convert to list
661
List<String> listFromIterator = IteratorUtils.toList(list1.iterator());
662
663
// Count elements
664
int count = IteratorUtils.size(list1.iterator()); // 3
665
666
// Check if iterator contains element
667
boolean contains = IteratorUtils.contains(list1.iterator(), "b"); // true
668
```
669
670
### Key IteratorUtils Methods
671
672
```java { .api }
673
/**
674
* Chains multiple iterators into a single iterator
675
*/
676
static <E> Iterator<E> chainedIterator(Iterator<? extends E>... iterators);
677
678
/**
679
* Creates an iterator that filters elements based on a predicate
680
*/
681
static <E> Iterator<E> filteredIterator(Iterator<? extends E> iterator, Predicate<? super E> predicate);
682
683
/**
684
* Creates an iterator that transforms elements using a transformer
685
*/
686
static <I, O> Iterator<O> transformedIterator(Iterator<? extends I> iterator, Transformer<? super I, ? extends O> transformer);
687
688
/**
689
* Gets the element at the specified index, returns null if out of bounds
690
*/
691
static <E> E get(Iterator<E> iterator, int index);
692
693
/**
694
* Converts iterator to a list
695
*/
696
static <E> List<E> toList(Iterator<? extends E> iterator);
697
698
/**
699
* Returns the number of elements in the iterator
700
*/
701
static int size(Iterator<?> iterator);
702
703
/**
704
* Checks if iterator contains the specified element
705
*/
706
static boolean contains(Iterator<?> iterator, Object object);
707
708
/**
709
* Creates an empty iterator
710
*/
711
static <E> Iterator<E> emptyIterator();
712
713
/**
714
* Creates a single-element iterator
715
*/
716
static <E> Iterator<E> singletonIterator(E object);
717
```
718
719
## IterableUtils - Iterable Operations
720
721
Utilities for working with Iterable objects, providing similar functionality to IteratorUtils but for iterables.
722
723
```java { .api }
724
import org.apache.commons.collections4.IterableUtils;
725
import java.util.List;
726
import java.util.Arrays;
727
728
List<String> list1 = Arrays.asList("apple", "banana", "cherry");
729
List<String> list2 = Arrays.asList("date", "elderberry");
730
731
// Chain multiple iterables
732
Iterable<String> chained = IterableUtils.chainedIterable(list1, list2);
733
// Contains: apple, banana, cherry, date, elderberry
734
735
// Filter iterable
736
Iterable<String> longFruits = IterableUtils.filteredIterable(list1, s -> s.length() > 5);
737
// Contains: banana, cherry
738
739
// Transform iterable
740
Iterable<String> upperCase = IterableUtils.transformedIterable(list1, String::toUpperCase);
741
// Contains: APPLE, BANANA, CHERRY
742
743
// Get element at index safely
744
String first = IterableUtils.get(list1, 0); // "apple"
745
String outOfBounds = IterableUtils.get(list1, 10); // null
746
747
// Check operations
748
boolean isEmpty = IterableUtils.isEmpty(list1); // false
749
boolean contains = IterableUtils.contains(list1, "banana"); // true
750
751
// Size and counting
752
int size = IterableUtils.size(list1); // 3
753
int matchCount = IterableUtils.frequency(list1, "apple"); // 1
754
755
// Convert to string
756
String joined = IterableUtils.toString(list1); // [apple, banana, cherry]
757
String custom = IterableUtils.toString(list1, item -> item.toUpperCase()); // [APPLE, BANANA, CHERRY]
758
```
759
760
### Key IterableUtils Methods
761
762
```java { .api }
763
/**
764
* Creates a chained iterable from multiple iterables
765
*/
766
static <E> Iterable<E> chainedIterable(Iterable<? extends E>... iterables);
767
768
/**
769
* Creates a filtered iterable based on a predicate
770
*/
771
static <E> Iterable<E> filteredIterable(Iterable<E> iterable, Predicate<? super E> predicate);
772
773
/**
774
* Creates a transformed iterable using a transformer
775
*/
776
static <I, O> Iterable<O> transformedIterable(Iterable<I> iterable, Transformer<? super I, ? extends O> transformer);
777
778
/**
779
* Gets element at specified index, returns null if out of bounds
780
*/
781
static <E> E get(Iterable<E> iterable, int index);
782
783
/**
784
* Checks if iterable is empty
785
*/
786
static boolean isEmpty(Iterable<?> iterable);
787
788
/**
789
* Returns the number of elements in the iterable
790
*/
791
static int size(Iterable<?> iterable);
792
793
/**
794
* Counts frequency of specified element
795
*/
796
static int frequency(Iterable<?> iterable, Object obj);
797
798
/**
799
* Converts iterable to string representation
800
*/
801
static String toString(Iterable<?> iterable);
802
```
803
804
## EnumerationUtils - Enumeration Operations
805
806
Utilities for working with the legacy Enumeration interface, providing conversions and operations.
807
808
```java { .api }
809
import org.apache.commons.collections4.EnumerationUtils;
810
import java.util.Enumeration;
811
import java.util.Vector;
812
import java.util.List;
813
import java.util.Iterator;
814
815
// Legacy code often uses Vector with Enumeration
816
Vector<String> vector = new Vector<>();
817
vector.add("item1");
818
vector.add("item2");
819
vector.add("item3");
820
821
Enumeration<String> enumeration = vector.elements();
822
823
// Convert enumeration to list
824
List<String> list = EnumerationUtils.toList(enumeration);
825
// Result: [item1, item2, item3]
826
827
// Convert enumeration to iterator (for modern iteration patterns)
828
Iterator<String> iterator = EnumerationUtils.asIterator(enumeration);
829
830
// Convert iterator to enumeration (when interfacing with legacy APIs)
831
Iterator<String> modernIterator = list.iterator();
832
Enumeration<String> legacyEnum = EnumerationUtils.asEnumeration(modernIterator);
833
834
// Get enumeration from iterable
835
Enumeration<String> fromIterable = EnumerationUtils.asEnumeration(list);
836
```
837
838
### Key EnumerationUtils Methods
839
840
```java { .api }
841
/**
842
* Converts an enumeration to a list
843
*/
844
static <E> List<E> toList(Enumeration<? extends E> enumeration);
845
846
/**
847
* Converts an enumeration to an iterator
848
*/
849
static <E> Iterator<E> asIterator(Enumeration<? extends E> enumeration);
850
851
/**
852
* Converts an iterator to an enumeration
853
*/
854
static <E> Enumeration<E> asEnumeration(Iterator<? extends E> iterator);
855
856
/**
857
* Converts an iterable to an enumeration
858
*/
859
static <E> Enumeration<E> asEnumeration(Iterable<? extends E> iterable);
860
```
861
862
Collection utilities in Apache Commons Collections provide powerful, null-safe operations for all common collection tasks. Use these utilities to write more robust, concise, and maintainable code while avoiding common pitfalls like null pointer exceptions and inefficient operations.