0
# Functional Programming
1
2
Eclipse Collections provides comprehensive functional programming support through Functions, Predicates, Procedures, and factory classes for common patterns. These interfaces enable powerful functional-style operations across all collection types.
3
4
## Capabilities
5
6
### Core Functional Interfaces
7
8
Base functional interfaces providing the foundation for all functional operations.
9
10
```java { .api }
11
/**
12
* Function interface for transforming objects of type T to type R
13
*/
14
interface Function<T, R> {
15
/**
16
* Transform the input argument to output value
17
* @param argument input value to transform
18
* @return transformed output value
19
*/
20
R valueOf(T argument);
21
}
22
23
/**
24
* Supplier function with no parameters returning type R
25
*/
26
interface Function0<R> {
27
/**
28
* Compute and return a value
29
* @return computed value
30
*/
31
R value();
32
}
33
34
/**
35
* Function interface for transforming two parameters to result type R
36
*/
37
interface Function2<T1, T2, R> {
38
/**
39
* Transform two input arguments to output value
40
* @param argument1 first input parameter
41
* @param argument2 second input parameter
42
* @return transformed output value
43
*/
44
R value(T1 argument1, T2 argument2);
45
}
46
47
/**
48
* Function interface for transforming three parameters to result type R
49
*/
50
interface Function3<T1, T2, T3, R> {
51
/**
52
* Transform three input arguments to output value
53
* @param argument1 first input parameter
54
* @param argument2 second input parameter
55
* @param argument3 third input parameter
56
* @return transformed output value
57
*/
58
R value(T1 argument1, T2 argument2, T3 argument3);
59
}
60
61
/**
62
* Predicate interface for testing conditions on objects of type T
63
*/
64
interface Predicate<T> {
65
/**
66
* Evaluate the predicate on the given argument
67
* @param object argument to evaluate
68
* @return true if argument satisfies predicate, false otherwise
69
*/
70
boolean accept(T object);
71
}
72
73
/**
74
* Two-parameter predicate interface
75
*/
76
interface Predicate2<T, P> {
77
/**
78
* Evaluate the predicate on the given arguments
79
* @param object first argument to evaluate
80
* @param parameter second argument to evaluate
81
* @return true if arguments satisfy predicate, false otherwise
82
*/
83
boolean accept(T object, P parameter);
84
}
85
86
/**
87
* Procedure interface for executing actions on objects of type T
88
*/
89
interface Procedure<T> {
90
/**
91
* Execute an action on the given argument
92
* @param object argument to process
93
*/
94
void value(T object);
95
}
96
97
/**
98
* Two-parameter procedure interface
99
*/
100
interface Procedure2<T, P> {
101
/**
102
* Execute an action on the given arguments
103
* @param object first argument to process
104
* @param parameter second argument to process
105
*/
106
void value(T object, P parameter);
107
}
108
109
/**
110
* Procedure interface for objects with int parameter
111
*/
112
interface ObjectIntProcedure<T> {
113
/**
114
* Execute action on object with int parameter
115
* @param object object to process
116
* @param index int parameter (often used as index)
117
*/
118
void value(T object, int index);
119
}
120
```
121
122
### Primitive Functional Interfaces
123
124
Functional interfaces for primitive types avoiding boxing overhead.
125
126
```java { .api }
127
// Int-specific functional interfaces
128
/**
129
* Function from objects to int primitives
130
*/
131
interface IntFunction<T> {
132
/**
133
* Transform object to int value
134
* @param object input object
135
* @return int result
136
*/
137
int intValueOf(T object);
138
}
139
140
/**
141
* Function from int primitives to objects
142
*/
143
interface IntToObjectFunction<R> {
144
/**
145
* Transform int to object value
146
* @param value input int
147
* @return transformed object
148
*/
149
R valueOf(int value);
150
}
151
152
/**
153
* Function from int to int
154
*/
155
interface IntToIntFunction {
156
/**
157
* Transform int to int value
158
* @param value input int
159
* @return transformed int
160
*/
161
int valueOf(int value);
162
}
163
164
/**
165
* Function with no parameters returning int
166
*/
167
interface IntFunction0 {
168
/**
169
* Compute and return int value
170
* @return computed int
171
*/
172
int value();
173
}
174
175
/**
176
* Two-parameter function returning int
177
*/
178
interface IntObjectToIntFunction<T> {
179
/**
180
* Transform object and int to int result
181
* @param object input object
182
* @param intParameter input int parameter
183
* @return transformed int result
184
*/
185
int intValueOf(T object, int intParameter);
186
}
187
188
/**
189
* Predicate for testing int values
190
*/
191
interface IntPredicate {
192
/**
193
* Test int value against predicate
194
* @param value int value to test
195
* @return true if value satisfies predicate
196
*/
197
boolean accept(int value);
198
}
199
200
/**
201
* Procedure for processing int values
202
*/
203
interface IntProcedure {
204
/**
205
* Execute action on int value
206
* @param value int value to process
207
*/
208
void value(int value);
209
}
210
211
/**
212
* Procedure for processing int pairs
213
*/
214
interface IntIntProcedure {
215
/**
216
* Execute action on two int values
217
* @param int1 first int value
218
* @param int2 second int value
219
*/
220
void value(int int1, int int2);
221
}
222
223
// Boolean-specific functional interfaces
224
/**
225
* Function from objects to boolean primitives
226
*/
227
interface BooleanFunction<T> {
228
boolean booleanValueOf(T object);
229
}
230
231
/**
232
* Function from boolean primitives to objects
233
*/
234
interface BooleanToObjectFunction<R> {
235
R valueOf(boolean value);
236
}
237
238
/**
239
* Predicate for testing boolean values
240
*/
241
interface BooleanPredicate {
242
boolean accept(boolean value);
243
}
244
245
/**
246
* Procedure for processing boolean values
247
*/
248
interface BooleanProcedure {
249
void value(boolean value);
250
}
251
252
// Similar patterns exist for: Byte, Char, Short, Long, Float, Double
253
// ByteFunction<T>, ByteToObjectFunction<R>, BytePredicate, ByteProcedure
254
// CharFunction<T>, CharToObjectFunction<R>, CharPredicate, CharProcedure
255
// ShortFunction<T>, ShortToObjectFunction<R>, ShortPredicate, ShortProcedure
256
// LongFunction<T>, LongToObjectFunction<R>, LongPredicate, LongProcedure
257
// FloatFunction<T>, FloatToObjectFunction<R>, FloatPredicate, FloatProcedure
258
// DoubleFunction<T>, DoubleToObjectFunction<R>, DoublePredicate, DoubleProcedure
259
```
260
261
### Predicates Factory
262
263
Factory class providing common predicates and predicate operations.
264
265
```java { .api }
266
/**
267
* Factory class for creating common predicates
268
*/
269
public final class Predicates {
270
/**
271
* Predicate that always returns true
272
* @return predicate that accepts all objects
273
*/
274
public static <T> Predicate<T> alwaysTrue();
275
276
/**
277
* Predicate that always returns false
278
* @return predicate that rejects all objects
279
*/
280
public static <T> Predicate<T> alwaysFalse();
281
282
/**
283
* Predicate that tests for null values
284
* @return predicate that accepts null objects
285
*/
286
public static Predicate<Object> isNull();
287
288
/**
289
* Predicate that tests for non-null values
290
* @return predicate that accepts non-null objects
291
*/
292
public static Predicate<Object> notNull();
293
294
/**
295
* Predicate that tests equality with expected value
296
* @param expected expected value for comparison
297
* @return predicate that accepts objects equal to expected
298
*/
299
public static Predicate<Object> equal(Object expected);
300
301
/**
302
* Predicate that tests inequality with expected value
303
* @param expected value to compare against
304
* @return predicate that accepts objects not equal to expected
305
*/
306
public static Predicate<Object> notEqual(Object expected);
307
308
/**
309
* Predicate that tests if object is instance of specified class
310
* @param clazz class to test against
311
* @return predicate that accepts instances of specified class
312
*/
313
public static Predicate<Object> instanceOf(Class<?> clazz);
314
315
/**
316
* Predicate that tests if object is assignable to specified class
317
* @param clazz class to test against
318
* @return predicate that accepts objects assignable to class
319
*/
320
public static Predicate<Object> assignableFrom(Class<?> clazz);
321
322
/**
323
* Predicate that tests membership in collection
324
* @param collection collection to test membership against
325
* @return predicate that accepts objects contained in collection
326
*/
327
public static Predicate<Object> in(Collection<?> collection);
328
329
/**
330
* Predicate that tests membership in iterable
331
* @param iterable iterable to test membership against
332
* @return predicate that accepts objects contained in iterable
333
*/
334
public static Predicate<Object> in(Iterable<?> iterable);
335
336
/**
337
* Predicate that tests non-membership in collection
338
* @param collection collection to test against
339
* @return predicate that accepts objects not in collection
340
*/
341
public static Predicate<Object> notIn(Collection<?> collection);
342
343
/**
344
* Predicate that tests non-membership in iterable
345
* @param iterable iterable to test against
346
* @return predicate that accepts objects not in iterable
347
*/
348
public static Predicate<Object> notIn(Iterable<?> iterable);
349
350
// Logical operations
351
/**
352
* Create logical AND of predicates
353
* @param predicates predicates to combine with AND
354
* @return predicate that requires all predicates to be true
355
*/
356
@SafeVarargs
357
public static <T> Predicate<T> and(Predicate<? super T>... predicates);
358
359
/**
360
* Create logical OR of predicates
361
* @param predicates predicates to combine with OR
362
* @return predicate that requires any predicate to be true
363
*/
364
@SafeVarargs
365
public static <T> Predicate<T> or(Predicate<? super T>... predicates);
366
367
/**
368
* Create logical NOT of predicate
369
* @param predicate predicate to negate
370
* @return predicate that returns opposite of input predicate
371
*/
372
public static <T> Predicate<T> not(Predicate<? super T> predicate);
373
374
// String-specific predicates
375
/**
376
* Predicate that tests if string starts with prefix
377
* @param prefix prefix to test for
378
* @return predicate for strings starting with prefix
379
*/
380
public static Predicate<String> startsWith(String prefix);
381
382
/**
383
* Predicate that tests if string ends with suffix
384
* @param suffix suffix to test for
385
* @return predicate for strings ending with suffix
386
*/
387
public static Predicate<String> endsWith(String suffix);
388
389
/**
390
* Predicate that tests if string contains substring
391
* @param substring substring to test for
392
* @return predicate for strings containing substring
393
*/
394
public static Predicate<String> contains(String substring);
395
396
/**
397
* Predicate that tests if string matches regex pattern
398
* @param pattern regex pattern to match
399
* @return predicate for strings matching pattern
400
*/
401
public static Predicate<String> matches(String pattern);
402
403
// Attribute-based predicates
404
/**
405
* Create predicate based on attribute extraction and testing
406
* @param function function to extract attribute from object
407
* @param predicate predicate to test extracted attribute
408
* @return composed predicate
409
*/
410
public static <T, V> Predicate<T> attributePredicate(Function<? super T, ? extends V> function, Predicate<? super V> predicate);
411
412
/**
413
* Create predicate testing if attribute equals expected value
414
* @param function function to extract attribute
415
* @param expectedValue expected attribute value
416
* @return predicate testing attribute equality
417
*/
418
public static <T, V> Predicate<T> attributeEqual(Function<? super T, ? extends V> function, V expectedValue);
419
420
/**
421
* Create predicate testing if attribute is greater than value
422
* @param function function to extract comparable attribute
423
* @param expectedValue value to compare against
424
* @return predicate testing attribute > expectedValue
425
*/
426
public static <T, V extends Comparable<? super V>> Predicate<T> attributeGreaterThan(Function<? super T, ? extends V> function, V expectedValue);
427
428
/**
429
* Create predicate testing if attribute is less than value
430
* @param function function to extract comparable attribute
431
* @param expectedValue value to compare against
432
* @return predicate testing attribute < expectedValue
433
*/
434
public static <T, V extends Comparable<? super V>> Predicate<T> attributeLessThan(Function<? super T, ? extends V> function, V expectedValue);
435
436
/**
437
* Create predicate testing if attribute is between values (inclusive)
438
* @param function function to extract comparable attribute
439
* @param lowerBound lower bound (inclusive)
440
* @param upperBound upper bound (inclusive)
441
* @return predicate testing lowerBound <= attribute <= upperBound
442
*/
443
public static <T, V extends Comparable<? super V>> Predicate<T> attributeBetween(Function<? super T, ? extends V> function, V lowerBound, V upperBound);
444
}
445
```
446
447
**Usage Examples:**
448
449
```java
450
import org.eclipse.collections.impl.block.factory.Predicates;
451
import org.eclipse.collections.impl.factory.Lists;
452
453
List<String> names = Lists.mutable.with("Alice", "Bob", "Charlie", "", null);
454
455
// Basic predicates
456
MutableList<String> nonNull = names.select(Predicates.notNull());
457
MutableList<String> nonEmpty = names.reject(Predicates.equal(""));
458
459
// String predicates
460
MutableList<String> startsWithA = names.select(Predicates.startsWith("A"));
461
MutableList<String> containsB = names.select(Predicates.contains("b"));
462
463
// Logical combinations
464
Predicate<String> validName = Predicates.and(
465
Predicates.notNull(),
466
Predicates.not(Predicates.equal(""))
467
);
468
MutableList<String> validNames = names.select(validName);
469
470
// Collection membership
471
Set<String> allowedNames = Sets.mutable.with("Alice", "Bob");
472
MutableList<String> allowed = names.select(Predicates.in(allowedNames));
473
474
// Attribute-based predicates
475
List<Person> people = Lists.mutable.with(
476
new Person("Alice", 25),
477
new Person("Bob", 35)
478
);
479
MutableList<Person> adults = people.select(
480
Predicates.attributeGreaterThan(Person::getAge, 18)
481
);
482
```
483
484
### Predicates2 Factory
485
486
Factory class for two-argument predicates.
487
488
```java { .api }
489
/**
490
* Factory class for creating two-argument predicates
491
*/
492
public final class Predicates2 {
493
/**
494
* Two-argument equality predicate
495
* @return predicate that tests if two arguments are equal
496
*/
497
public static Predicate2<Object, Object> equal();
498
499
/**
500
* Two-argument inequality predicate
501
* @return predicate that tests if two arguments are not equal
502
*/
503
public static Predicate2<Object, Object> notEqual();
504
505
/**
506
* Two-argument less-than predicate for comparables
507
* @return predicate that tests if first < second
508
*/
509
public static <T extends Comparable<? super T>> Predicate2<T, T> lessThan();
510
511
/**
512
* Two-argument greater-than predicate for comparables
513
* @return predicate that tests if first > second
514
*/
515
public static <T extends Comparable<? super T>> Predicate2<T, T> greaterThan();
516
517
/**
518
* Two-argument less-than-or-equal predicate for comparables
519
* @return predicate that tests if first <= second
520
*/
521
public static <T extends Comparable<? super T>> Predicate2<T, T> lessThanOrEqualTo();
522
523
/**
524
* Two-argument greater-than-or-equal predicate for comparables
525
* @return predicate that tests if first >= second
526
*/
527
public static <T extends Comparable<? super T>> Predicate2<T, T> greaterThanOrEqualTo();
528
529
/**
530
* Predicate testing if first argument is contained in second (iterable)
531
* @return predicate that tests membership
532
*/
533
public static Predicate2<Object, Iterable<?>> in();
534
535
/**
536
* Predicate testing if first argument is instance of second (class)
537
* @return predicate that tests instance relationship
538
*/
539
public static Predicate2<Object, Class<?>> instanceOf();
540
541
/**
542
* Predicate testing if first argument is null and second is ignored
543
* @return predicate that tests nullness of first argument
544
*/
545
public static Predicate2<Object, Object> isNull();
546
547
/**
548
* Predicate testing if first argument is not null and second is ignored
549
* @return predicate that tests non-nullness of first argument
550
*/
551
public static Predicate2<Object, Object> notNull();
552
}
553
```
554
555
### Functions Factory
556
557
Factory class providing common functions and function operations.
558
559
```java { .api }
560
/**
561
* Factory class for creating common functions
562
*/
563
public final class Functions {
564
/**
565
* Identity function that returns its argument unchanged
566
* @return function that returns input argument
567
*/
568
public static <T> Function<T, T> getPassThru();
569
570
/**
571
* Function that returns a fixed value regardless of input
572
* @param value fixed value to return
573
* @return function that always returns the specified value
574
*/
575
public static <T, V> Function<T, V> getFixedValue(V value);
576
577
/**
578
* Function that converts objects to strings using toString()
579
* @return function that converts objects to strings
580
*/
581
public static Function<Object, String> getToString();
582
583
/**
584
* Function that parses strings to integers
585
* @return function that converts strings to integers
586
*/
587
public static Function<String, Integer> getStringToInteger();
588
589
/**
590
* Function that parses strings to doubles
591
* @return function that converts strings to doubles
592
*/
593
public static Function<String, Double> getStringToDouble();
594
595
/**
596
* Function that gets the class of an object
597
* @return function that returns object's class
598
*/
599
public static Function<Object, Class<?>> getToClass();
600
601
/**
602
* Function that gets the size/length of collections/strings/arrays
603
* @return function that returns size of sized objects
604
*/
605
public static Function<Object, Integer> getSizeOf();
606
607
// Chain functions
608
/**
609
* Chain two functions together (composition)
610
* @param function1 first function to apply
611
* @param function2 second function to apply to result of first
612
* @return composed function
613
*/
614
public static <T, I, V> Function<T, V> chain(Function<? super T, ? extends I> function1, Function<? super I, ? extends V> function2);
615
616
/**
617
* Chain three functions together
618
* @param function1 first function
619
* @param function2 second function
620
* @param function3 third function
621
* @return composed function of all three
622
*/
623
public static <T, I1, I2, V> Function<T, V> chain(Function<? super T, ? extends I1> function1, Function<? super I1, ? extends I2> function2, Function<? super I2, ? extends V> function3);
624
625
// Conditional functions
626
/**
627
* Function that returns first non-null result from trying multiple functions
628
* @param functions functions to try in order
629
* @return function that returns first non-null result
630
*/
631
@SafeVarargs
632
public static <T, V> Function<T, V> firstNotNullValue(Function<? super T, ? extends V>... functions);
633
634
/**
635
* Function that returns first non-empty string from trying multiple functions
636
* @param functions functions to try in order
637
* @return function that returns first non-empty string result
638
*/
639
@SafeVarargs
640
public static <T> Function<T, String> firstNotEmptyStringValue(Function<? super T, String>... functions);
641
642
// Conditional function application
643
/**
644
* Apply one of two functions based on predicate test
645
* @param predicate predicate to test input
646
* @param trueFunction function to apply if predicate is true
647
* @param falseFunction function to apply if predicate is false
648
* @return conditional function
649
*/
650
public static <T, V> Function<T, V> ifTrue(Predicate<? super T> predicate, Function<? super T, ? extends V> trueFunction, Function<? super T, ? extends V> falseFunction);
651
652
/**
653
* Apply function only if predicate is true, otherwise return null
654
* @param predicate predicate to test
655
* @param function function to apply if true
656
* @return conditional function
657
*/
658
public static <T, V> Function<T, V> ifTrue(Predicate<? super T> predicate, Function<? super T, ? extends V> function);
659
660
// Attribute extraction functions
661
/**
662
* Function that extracts a key using a key function, for use in maps
663
* @param keyFunction function to extract key from value
664
* @return function for key extraction
665
*/
666
public static <T, K> Function<T, K> getKeyFunction(Function<? super T, K> keyFunction);
667
668
/**
669
* Function that extracts a value using a value function, for use in maps
670
* @param valueFunction function to extract value
671
* @return function for value extraction
672
*/
673
public static <T, V> Function<T, V> getValueFunction(Function<? super T, V> valueFunction);
674
675
// Synchronization wrapper
676
/**
677
* Create synchronized wrapper around a function
678
* @param function function to synchronize
679
* @return synchronized function wrapper
680
*/
681
public static <T, V> Function<T, V> synchronizedEach(Function<T, V> function);
682
683
// Collection-specific functions
684
/**
685
* Function that converts iterables to lists
686
* @return function that creates lists from iterables
687
*/
688
public static <T> Function<Iterable<T>, MutableList<T>> toList();
689
690
/**
691
* Function that converts iterables to sets
692
* @return function that creates sets from iterables
693
*/
694
public static <T> Function<Iterable<T>, MutableSet<T>> toSet();
695
696
/**
697
* Function that gets the first element from an iterable
698
* @return function that returns first element
699
*/
700
public static <T> Function<Iterable<T>, T> firstOfIterable();
701
702
/**
703
* Function that gets the last element from an iterable
704
* @return function that returns last element
705
*/
706
public static <T> Function<Iterable<T>, T> lastOfIterable();
707
}
708
```
709
710
**Usage Examples:**
711
712
```java
713
import org.eclipse.collections.impl.block.factory.Functions;
714
715
MutableList<String> strings = Lists.mutable.with("123", "456", "789");
716
717
// Basic functions
718
MutableList<Integer> lengths = strings.collect(Functions.getSizeOf());
719
MutableList<String> upperCase = strings.collect(String::toUpperCase);
720
721
// Chain functions
722
Function<String, String> parseAndFormat = Functions.chain(
723
Functions.getStringToInteger(),
724
Object::toString
725
);
726
727
// Fixed value function
728
MutableList<String> constants = Lists.mutable.with("a", "b", "c")
729
.collect(Functions.getFixedValue("constant"));
730
731
// Conditional functions
732
Function<String, Integer> safeParseInt = Functions.ifTrue(
733
Predicates.notNull(),
734
Functions.getStringToInteger(),
735
Functions.getFixedValue(0)
736
);
737
738
// First non-null value
739
Function<Person, String> getAnyName = Functions.firstNotNullValue(
740
Person::getNickname,
741
Person::getFirstName,
742
Functions.getFixedValue("Unknown")
743
);
744
```
745
746
### Comparators Factory
747
748
Factory class for creating common comparators.
749
750
```java { .api }
751
/**
752
* Factory class for creating common comparators
753
*/
754
public final class Comparators {
755
/**
756
* Natural order comparator for comparable objects
757
* @return comparator using natural ordering
758
*/
759
public static <T extends Comparable<? super T>> Comparator<T> naturalOrder();
760
761
/**
762
* Reverse natural order comparator
763
* @return comparator using reverse natural ordering
764
*/
765
public static <T extends Comparable<? super T>> Comparator<T> reverseNaturalOrder();
766
767
/**
768
* Comparator that compares objects by the result of a function
769
* @param function function to extract comparable value
770
* @return comparator based on function result
771
*/
772
public static <T, V extends Comparable<? super V>> Comparator<T> byFunction(Function<? super T, ? extends V> function);
773
774
/**
775
* Comparator that compares objects by function result in reverse order
776
* @param function function to extract comparable value
777
* @return reverse comparator based on function result
778
*/
779
public static <T, V extends Comparable<? super V>> Comparator<T> byFunctionReverse(Function<? super T, ? extends V> function);
780
781
/**
782
* Chain multiple comparators together
783
* @param comparators comparators to chain
784
* @return comparator that applies comparators in sequence
785
*/
786
@SafeVarargs
787
public static <T> Comparator<T> chain(Comparator<T>... comparators);
788
789
/**
790
* Comparator that handles nulls by placing them first
791
* @param comparator comparator for non-null values
792
* @return null-safe comparator with nulls first
793
*/
794
public static <T> Comparator<T> nullsFirst(Comparator<T> comparator);
795
796
/**
797
* Comparator that handles nulls by placing them last
798
* @param comparator comparator for non-null values
799
* @return null-safe comparator with nulls last
800
*/
801
public static <T> Comparator<T> nullsLast(Comparator<T> comparator);
802
803
/**
804
* Comparator for strings ignoring case
805
* @return case-insensitive string comparator
806
*/
807
public static Comparator<String> caseInsensitive();
808
809
/**
810
* Reverse a comparator's ordering
811
* @param comparator comparator to reverse
812
* @return reversed comparator
813
*/
814
public static <T> Comparator<T> reverse(Comparator<T> comparator);
815
816
/**
817
* Create comparator for power set ordering
818
* @param comparator element comparator
819
* @return power set comparator
820
*/
821
public static <T> Comparator<Iterable<T>> powerSet(Comparator<T> comparator);
822
823
// Primitive comparators
824
/**
825
* Comparator for int values
826
* @return int comparator
827
*/
828
public static Comparator<Integer> intNaturalOrder();
829
830
/**
831
* Comparator for long values
832
* @return long comparator
833
*/
834
public static Comparator<Long> longNaturalOrder();
835
836
/**
837
* Comparator for double values
838
* @return double comparator
839
*/
840
public static Comparator<Double> doubleNaturalOrder();
841
}
842
```
843
844
### Procedures Factory
845
846
Factory class for creating common procedures.
847
848
```java { .api }
849
/**
850
* Factory class for creating common procedures
851
*/
852
public final class Procedures {
853
/**
854
* Procedure that does nothing (no-op)
855
* @return procedure that performs no action
856
*/
857
public static <T> Procedure<T> noop();
858
859
/**
860
* Procedure that prints objects using System.out.println
861
* @return procedure that prints to standard output
862
*/
863
public static Procedure<Object> println();
864
865
/**
866
* Procedure that prints objects using System.out.print
867
* @return procedure that prints to standard output without newline
868
*/
869
public static Procedure<Object> print();
870
871
/**
872
* Procedure that adds elements to a collection
873
* @param collection target collection to add to
874
* @return procedure that adds elements to collection
875
*/
876
public static <T> Procedure<T> addToCollection(Collection<T> collection);
877
878
/**
879
* Procedure that removes elements from a collection
880
* @param collection target collection to remove from
881
* @return procedure that removes elements from collection
882
*/
883
public static <T> Procedure<T> removeFromCollection(Collection<T> collection);
884
885
/**
886
* Procedure that throws runtime exception
887
* @param runtimeException exception to throw
888
* @return procedure that throws the specified exception
889
*/
890
public static <T> Procedure<T> throwException(RuntimeException runtimeException);
891
892
/**
893
* Synchronized wrapper around a procedure
894
* @param procedure procedure to synchronize
895
* @return synchronized procedure wrapper
896
*/
897
public static <T> Procedure<T> synchronizedEach(Procedure<T> procedure);
898
899
/**
900
* Chain multiple procedures together
901
* @param procedures procedures to execute in sequence
902
* @return procedure that executes all procedures
903
*/
904
@SafeVarargs
905
public static <T> Procedure<T> chain(Procedure<? super T>... procedures);
906
907
/**
908
* Conditional procedure execution
909
* @param predicate condition to test
910
* @param procedure procedure to execute if condition is true
911
* @return conditional procedure
912
*/
913
public static <T> Procedure<T> ifTrue(Predicate<? super T> predicate, Procedure<? super T> procedure);
914
915
/**
916
* Procedure that executes different procedures based on predicate
917
* @param predicate condition to test
918
* @param trueProcedure procedure if predicate is true
919
* @param falseProcedure procedure if predicate is false
920
* @return conditional procedure
921
*/
922
public static <T> Procedure<T> ifElse(Predicate<? super T> predicate, Procedure<? super T> trueProcedure, Procedure<? super T> falseProcedure);
923
924
// Object mutation procedures
925
/**
926
* Procedure that sets a field value using reflection
927
* @param fieldName name of field to set
928
* @param value value to set field to
929
* @return procedure that sets field value
930
*/
931
public static <T> Procedure<T> setFieldValue(String fieldName, Object value);
932
933
/**
934
* Procedure that invokes a method using reflection
935
* @param methodName name of method to invoke
936
* @param arguments arguments to pass to method
937
* @return procedure that invokes method
938
*/
939
public static <T> Procedure<T> invokeMethod(String methodName, Object... arguments);
940
}
941
```
942
943
## Advanced Functional Patterns
944
945
### Function Composition
946
947
Eclipse Collections supports advanced function composition patterns:
948
949
```java
950
import org.eclipse.collections.impl.block.factory.Functions;
951
import org.eclipse.collections.impl.block.factory.Predicates;
952
953
// Chain multiple transformations
954
Function<String, Integer> parseAndSquare = Functions.chain(
955
Integer::valueOf, // String -> Integer
956
x -> x * x // Integer -> Integer (squared)
957
);
958
959
// Conditional function application
960
Function<String, String> safeToUpper = Functions.ifTrue(
961
Predicates.notNull(), // Only apply if not null
962
String::toUpperCase, // Transform to upper case
963
Functions.getFixedValue("") // Return empty string if null
964
);
965
966
// First non-null result
967
Function<Person, String> getBestContactInfo = Functions.firstNotNullValue(
968
Person::getEmail, // Try email first
969
Person::getPhoneNumber, // Then phone
970
Person::getAddress, // Then address
971
Functions.getFixedValue("No contact info") // Default
972
);
973
974
List<String> inputs = Lists.mutable.with("5", "10", null, "15");
975
List<Integer> squares = inputs.collect(parseAndSquare); // [25, 100, null, 225]
976
List<String> safe = inputs.collect(safeToUpper); // ["5", "10", "", "15"]
977
```
978
979
### Custom Functional Interfaces
980
981
Create domain-specific functional interfaces:
982
983
```java
984
// Custom functional interfaces for domain logic
985
@FunctionalInterface
986
interface PriceCalculator extends Function<Product, BigDecimal> {
987
BigDecimal valueOf(Product product);
988
989
default PriceCalculator withTax(BigDecimal taxRate) {
990
return product -> this.valueOf(product).multiply(BigDecimal.ONE.add(taxRate));
991
}
992
993
default PriceCalculator withDiscount(BigDecimal discountPercent) {
994
return product -> this.valueOf(product).multiply(BigDecimal.ONE.subtract(discountPercent.divide(BigDecimal.valueOf(100))));
995
}
996
}
997
998
@FunctionalInterface
999
interface OrderValidator extends Predicate<Order> {
1000
boolean accept(Order order);
1001
1002
default OrderValidator and(OrderValidator other) {
1003
return order -> this.accept(order) && other.accept(order);
1004
}
1005
1006
default OrderValidator or(OrderValidator other) {
1007
return order -> this.accept(order) || other.accept(order);
1008
}
1009
}
1010
1011
// Usage
1012
PriceCalculator basePrice = Product::getBasePrice;
1013
PriceCalculator finalPrice = basePrice
1014
.withDiscount(BigDecimal.valueOf(10)) // 10% discount
1015
.withTax(BigDecimal.valueOf(0.08)); // 8% tax
1016
1017
OrderValidator hasItems = order -> !order.getItems().isEmpty();
1018
OrderValidator hasCustomer = order -> order.getCustomer() != null;
1019
OrderValidator isValid = hasItems.and(hasCustomer);
1020
1021
List<Product> products = getProducts();
1022
List<BigDecimal> prices = products.collect(finalPrice);
1023
1024
List<Order> orders = getOrders();
1025
List<Order> validOrders = orders.select(isValid);
1026
```
1027
1028
### Performance Considerations
1029
1030
Functional programming in Eclipse Collections is optimized for performance:
1031
1032
1. **Lazy evaluation**: Use `asLazy()` for deferred computation
1033
2. **Primitive specializations**: Use primitive functional interfaces to avoid boxing
1034
3. **Method references**: Prefer method references over lambdas for better performance
1035
4. **Predicate combination**: Use factory methods for optimal predicate combination
1036
1037
```java
1038
// Optimized functional pipeline
1039
MutableList<Integer> numbers = IntLists.mutable.with(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
1040
.toList(); // Convert to object list only when needed
1041
1042
// Efficient lazy chain
1043
LazyIterable<String> result = numbers
1044
.asLazy() // Switch to lazy evaluation
1045
.select(x -> x % 2 == 0) // Filter evens: [2, 4, 6, 8, 10]
1046
.collect(x -> x * x) // Square: [4, 16, 36, 64, 100]
1047
.select(x -> x > 20) // Filter > 20: [36, 64, 100]
1048
.collect(Object::toString); // Convert to strings
1049
1050
// Only computed when terminal operation called
1051
MutableList<String> computed = result.toList(); // ["36", "64", "100"]
1052
1053
// Primitive functional operations avoid boxing
1054
MutableIntList primitiveNumbers = IntLists.mutable.with(1, 2, 3, 4, 5);
1055
long sum = primitiveNumbers
1056
.select(x -> x % 2 == 0) // IntPredicate - no boxing
1057
.collect(x -> x * x) // IntToIntFunction - no boxing
1058
.sum(); // Primitive sum - no boxing
1059
```