-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMethodReferences.java
More file actions
137 lines (122 loc) · 4.7 KB
/
Copy pathMethodReferences.java
File metadata and controls
137 lines (122 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package Phase2_MethodsArraysStrings.Methods;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Method References (Java 8+)
* ---------------------------
* A method reference is a compact, expressive ALTERNATIVE TO A LAMBDA when the
* lambda just calls an existing method. Syntax:
* <p>
*
* Target::methodName
* <p>
*
* Four Forms of Method References
* -------------------------------
* <p>
*
* 1. STATIC method Class::staticMethod
* <p>
*
* Function<String, Integer> p = Integer::parseInt;
* // equivalent lambda: s -> Integer.parseInt(s)
* <p>
*
* 2. INSTANCE method of a PARTICULAR object instance::method
* <p>
*
* StringBuilder sb = new StringBuilder();
* Consumer<String> append = sb::append;
* // equivalent lambda: s -> sb.append(s)
* <p>
*
* 3. INSTANCE method of an ARBITRARY object of a type Class::method
* <p>
*
* Function<String, Integer> len = String::length;
* // equivalent lambda: s -> s.length()
* <p>
*
* 4. CONSTRUCTOR reference Class::new
* <p>
*
* Supplier<ArrayList<String>> mk = ArrayList::new;
* Function<String, StringBuilder> wrap = StringBuilder::new;
* <p>
*
* Why Use Them?
* -------------
* - Less noise than the equivalent lambda.
* - Reads almost like English: "stream of names, sort by String::length".
* - Encourages thinking in terms of WHAT to apply rather than HOW.
* <p>
*
* When To Stick With a Lambda
* ---------------------------
* - When the lambda needs additional logic beyond a single method call.
* - When the type inference for `::` gets confused.
* - When readability suffers (overloaded methods + method references can be
* hard to read).
*/
public class MethodReferences {
public static void main(String[] args) {
// --- 1) Static method reference - Integer::parseInt ---
Function<String, Integer> parse = Integer::parseInt;
System.out.println("parse.apply(\"42\") = " + parse.apply("42"));
// --- 2) Instance method of a particular object - sb::append ---
StringBuilder sb = new StringBuilder("start");
java.util.function.Consumer<String> append = sb::append;
append.accept(" + more");
append.accept(" + extra");
System.out.println("sb after appends = " + sb);
// --- 3) Instance method of an arbitrary object - String::length ---
Function<String, Integer> length = String::length;
System.out.println("length.apply(\"hi\") = " + length.apply("hi"));
// --- 4) Constructor reference - StringBuilder::new ---
Function<String, StringBuilder> wrap = StringBuilder::new;
StringBuilder wrapped = wrap.apply("created via ::new");
System.out.println("wrapped = " + wrapped);
Supplier<java.util.ArrayList<String>> mkList = java.util.ArrayList::new;
java.util.ArrayList<String> fresh = mkList.get();
fresh.add("hello");
System.out.println("fresh list = " + fresh);
// --- 5) Combined with Streams - the real-world payoff ---
List<String> names = Arrays.asList("Charlie", "Alice", "bob", "Dave");
names.stream()
.map(String::toUpperCase) // arbitrary-object instance method ref
.sorted()
.forEach(System.out::println); // particular-object instance method ref
// Sort by length using a method-reference comparator
names.stream()
.sorted(java.util.Comparator.comparingInt(String::length))
.forEach(s -> System.out.println(s.length() + " - " + s));
// --- 6) BiFunction with two arguments via static method reference ---
BiFunction<Integer, Integer, Integer> max = Math::max;
System.out.println("max(3, 7) = " + max.apply(3, 7));
// --- 7) Predicate via method reference ---
Predicate<String> isEmpty = String::isEmpty;
System.out.println("isEmpty(\"\") = " + isEmpty.test(""));
System.out.println("isEmpty(\"x\") = " + isEmpty.test("x"));
// OUTPUT
// parse.apply("42") = 42
// sb after appends = start + more + extra
// length.apply("hi") = 2
// wrapped = created via ::new
// fresh list = [hello]
// ALICE
// BOB
// CHARLIE
// DAVE
// 3 - bob
// 4 - Dave
// 5 - Alice
// 7 - Charlie
// max(3, 7) = 7
// isEmpty("") = true
// isEmpty("x") = false
}
}