-
Notifications
You must be signed in to change notification settings - Fork 90
/
ch11.html
641 lines (435 loc) · 37.5 KB
/
ch11.html
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
<!doctype html>
<html lang="en">
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Study guide for the Oracle Certified Professional, Java SE 8 Programmer Exam ">
<title>Java 8 Programmer II Study Guide: Exam 1Z0-809</title>
<link href="css/code.css" rel="stylesheet" type="text/css" />
<link href="css/style.css" rel="stylesheet" type="text/css" />
<link href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="js/common-sections.js"></script>
</head>
<body>
<div class="nav"></div>
<div class="header">
<div class="title-container">
<div class="chapter-title">
<h1><i class="chapter">Chapter ELEVEN</i><br />
Method References</h1>
<p><br /></p>
<h3 style="text-align: center;"><i>Exam Objectives</i></h3>
<p style="text-align: center;"><i>Use method references with Streams.</i><br /></p>
</div>
</div>
</div>
<div class="container">
<div class="column">
<h2>Using methods like objects</h2>
<p>As we know, in Java we can use references to objects, either by creating new objects:</p>
<p><code class="java hljs">List list = <span class="hljs-keyword">new</span> ArrayList();<br />
store(<span class="hljs-keyword">new</span> ArrayList());</code></p>
<p>Or by using existing objects:</p>
<p><code class="java hljs">List list2 = list;<br />
isFull(list2);</code></p>
<p>But what about a reference to a <i>method</i>?</p>
<p>If we only use a method of an object in another method, we still have to pass the full object as an argument. Wouldn't be more practical just to pass the method as an argument? Like this for example:</p>
<p><code class="java hljs">isFull(list.size);</code></p>
<p>In Java 8, thanks to lambda expressions, we can do something like that. We can use methods like if they were objects or primitive values.</p>
<p>And that's because a method reference is the shorthand syntax for a lambda expression that executes just <b>ONE</b> method.</p>
<hr />
<h4><i>A Method Reference</i></h4>
<p><code class="java hljs">Object :: methodName</code></p>
<hr />
<p>We know that we can use lambda expressions instead of using an anonymous class. But sometimes, the lambda expression is really just a call to some method, for example:</p>
<p><code class="java hljs">Consumer<String> c = s -> System.out.println(s);</code></p>
<p>To make the code clearer, you can turn that lambda expression into a method reference:</p>
<p><code class="java hljs">Consumer<String> c = System.out::println;</code></p>
<p>In a method reference, you place the object (or class) that contains the method before the <code>::</code> operator and the name of the method after it without arguments.</p>
<p>But you may be thinking:</p>
<ul>
<li>How is this clearer?</li>
<li>What happen to the arguments?</li>
<li>How can this be a valid expression?</li>
<li>I don't understand how to construct a valid method reference</li>
</ul>
<p>First of all, a methods reference can't be used for any method. <b>They can be used only to replace a single-method lambda expression</b>.</p>
<p>So to use a method reference you first need a lambda expression with one method. And to use a lambda expression you first need a functional interface, an interface with just one abstract method.</p>
<p>In other words:</p>
<p style="text-align: center;">Instead of using</p>
<p style="text-align: center;"><br /></p>
<p style="text-align: center;"><b>AN ANONYMOUS CLASS</b></p>
<p style="text-align: center;"><br /></p>
<p style="text-align: center;">you can use</p>
<p style="text-align: center;"><br /></p>
<p style="text-align: center;"><b>A LAMBDA EXPRESSION</b></p>
<p style="text-align: center;"><br /></p>
<p style="text-align: center;">And if this just calls one method, you can use</p>
<p style="text-align: center;"><br /></p>
<p style="text-align: center;"><b>A METHOD REFERENCE</b></p>
<p><br /></p>
<p>There are four types of method references:</p>
<ul>
<li>A method reference to a <i>static method</i><br /></li>
<li>A method reference to an <i>instance method of an object of a particular type</i><br /></li>
<li>A method reference to an <i>instance method of an existing object</i><br /></li>
<li>A method reference to a <i>constructor</i><br /></li>
</ul>
<p>Let's begin by explaining the most natural case, a <i>static method</i>.</p>
<h2>Static Method</h2>
<p>In this case, we have a lambda expression like the following:</p>
<p><code class="java hljs">(args) -> Class.staticMethod(args)</code></p>
<p>That can be turned into the following method reference:</p>
<p><code class="java hljs">Class::staticMethod</code></p>
<p>Notice that between a static method and a static method reference instead of the . operator, we use the :: operator, and that we don't pass arguments to the method reference.</p>
<p>In general, we don't have to pass arguments to method references. However, arguments are treated depending on the type of method reference.</p>
<p>In this case, any arguments (if any) taken by the method are passed automatically behind the curtains.</p>
<p>Wherever we can pass a lambda expression that just calls a static method, we can use a method reference. For example, assuming this class:</p>
<p><code class="java hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Numbers</span></span> {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isMoreThanFifty</span><span class="hljs-params">(<span class="hljs-keyword">int</span> n1, <span class="hljs-keyword">int</span> n2)</span></span> {<br />
<span class="hljs-keyword">return</span> (n1 + n2) > <span class="hljs-number">50</span>;<br />
}<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> List<Integer> <span class="hljs-title">findNumbers</span><span class="hljs-params">(<br />
List<Integer> l, BiPredicate<Integer, Integer> p)</span></span> {<br />
List<Integer> newList = <span class="hljs-keyword">new</span> ArrayList<>();<br />
<span class="hljs-keyword">for</span>(Integer i : l) {<br />
<span class="hljs-keyword">if</span>(p.test(i, i + <span class="hljs-number">10</span>)) {<br />
newList.add(i);<br />
}<br />
}<br />
<span class="hljs-keyword">return</span> newList;<br />
}<br />
}</code></p>
<p>We can call the <code>findNumbers()</code> method:</p>
<p><code class="java hljs">List<Integer> list = Arrays.asList(<span class="hljs-number">12</span>,<span class="hljs-number">5</span>,<span class="hljs-number">45</span>,<span class="hljs-number">18</span>,<span class="hljs-number">33</span>,<span class="hljs-number">24</span>,<span class="hljs-number">40</span>);<br />
<br />
<span class="hljs-comment">// Using an anonymous class</span><br />
findNumbers(list, <span class="hljs-keyword">new</span> BiPredicate<Integer, Integer>() {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">test</span><span class="hljs-params">(Integer i1, Integer i2)</span></span> {<br />
<span class="hljs-keyword">return</span> Numbers.isMoreThanFifty(i1, i2);<br />
}<br />
});<br />
<br />
<span class="hljs-comment">// Using a lambda expression</span><br />
findNumbers(list, (i1, i2) -> Numbers.isMoreThanFifty(i1, i2));<br />
<br />
<span class="hljs-comment">// Using a method reference</span><br />
findNumbers(list, Numbers::isMoreThanFifty);</code></p>
<h2>Instance method of an object of a particular type</h2>
<p>In this case, we have a lambda expression like the following:</p>
<p><code class="java hljs">(obj, args) -> obj.instanceMethod(args)</code></p>
<p>Where an instance of an object is passed, and one of its methods is executed with some optional(s) parameter(s).</p>
<p>That can be turned into the following method reference:</p>
<p><code class="java hljs">ObjectType::instanceMethod</code></p>
<p>This time, the conversion is not that straightforward. First, in the method reference, we don't use the instance itself. We use its type.</p>
<p>Second, the other argument of the lambda expression, if any, it's not used in the method reference, but it's passed behind the curtains like in the static method case.</p>
<p>For example, assuming this class:</p>
<p><code class="java hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Shipment</span></span> {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">calculateWeight</span><span class="hljs-params">()</span></span> {<br />
<span class="hljs-keyword">double</span> weight = <span class="hljs-number">0</span>;<br />
<span class="hljs-comment">// Calculate weight<br /></span> <span class="hljs-keyword">return</span> weight;<br />
}<br />
}</code></p>
<p>And this method:</p>
<p><code class="java hljs"><span class="hljs-function"><span class="hljs-keyword">public</span> List<Double> <span class="hljs-title">calculateOnShipments</span><span class="hljs-params">(<br />
List<Shipment> l, Function<Shipment, Double> f)</span></span> {<br />
List<Double> results = <span class="hljs-keyword">new</span> ArrayList<>();<br />
<span class="hljs-keyword">for</span>(Shipment s : l) {<br />
results.add(f.apply(s));<br />
}<br />
<span class="hljs-keyword">return</span> results;<br />
}</code></p>
<p>We can call that method using:</p>
<p><code class="java hljs">List<Shipment> l = <span class="hljs-keyword">new</span> ArrayList<Shipment>();<br />
<br />
<span class="hljs-comment">// Using an anonymous class</span><br />
calculateOnShipments(l, <span class="hljs-keyword">new</span> Function<Shipment, Double>() {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> Double <span class="hljs-title">apply</span><span class="hljs-params">(Shipment s)</span></span> { <span class="hljs-comment">// The object<br /></span> <span class="hljs-keyword">return</span> s.calculateWeight(); <span class="hljs-comment">// The method<br /></span> }<br />
});<br />
<br />
<span class="hljs-comment">// Using a lambda expression</span><br />
calculateOnShipments(l, s -> s.calculateWeight());<br />
<br />
<span class="hljs-comment">// Using a method reference</span><br />
calculateOnShipments(l, Shipment::calculateWeight);</code></p>
<p>In this example, we don't pass any arguments to the method. The key point here is that an instance of the object is the parameter of the lambda expression, and we form the reference to the instance method with the type of the instance.</p>
<p>Here's another example where we pass two arguments to the method reference.</p>
<p>Java has a <code>Function</code> interface that takes one parameter, a <code>BiFunction</code> that takes two parameters, but there's no <code>TriFunction</code> that takes three parameters, so let's make one:</p>
<p><code class="java hljs"><span class="hljs-keyword">interface</span> TriFunction<T, U, V, R> {<br />
R apply(T t, U u, V v);<br />
}</code></p>
<p>Now assume a class with a method that takes two parameters and return a result, like this:</p>
<p><code class="java hljs"><span class="hljs-keyword">class</span> Sum {<br />
Integer doSum(String s1, String s2) {<br />
<span class="hljs-keyword">return</span> Integer.parseInt(s1) + Integer.parseInt(s2);<br />
}<br />
}</code></p>
<p>We can wrap the <code>doSum()</code> method within a <code>TriFunction</code> implementation using an anonymous class:</p>
<p><code class="java hljs">TriFunction<Sum, String, String, Integer> anon =<br />
<span class="hljs-keyword">new</span> TriFunction<Sum, String, String, Integer>() {<br />
@Override<br />
<span class="hljs-keyword">public</span> Integer apply(Sum s, String arg1, String arg2) {<br />
<span class="hljs-keyword">return</span> s.doSum(arg1, arg2);<br />
}<br />
};<br />
System.out.println(anon.apply(<span class="hljs-keyword">new</span> Sum(), <span class="hljs-string">"1"</span>, <span class="hljs-string">"4"</span>));</code></p>
<p>Or using a lambda expression:</p>
<p><code class="java hljs">TriFunction<Sum, String, String, Integer> lambda =<br />
(Sum s, String arg1, String arg2) -> s.doSum(arg1, arg2);<br />
System.out.println(lambda.apply(<span class="hljs-keyword">new</span> Sum(), <span class="hljs-string">"1"</span>, <span class="hljs-string">"4"</span>));</code></p>
<p>Or just using a method reference:</p>
<p><code class="java hljs">TriFunction<Sum, String, String, Integer> mRef = Sum::doSum;<br />
System.out.println(mRef.apply(<span class="hljs-keyword">new</span> Sum(), <span class="hljs-string">"1"</span>, <span class="hljs-string">"4"</span>));</code></p>
<p>Here:</p>
<ul>
<li>The first type parameter of <code>TriFunction</code> is the object type that contains the method to execute.</li>
<li>The second type parameter of <code>TriFunction</code> is the type of the first parameter.</li>
<li>The third type parameter of <code>TriFunction</code> is the type of the second parameter.</li>
<li>The last type parameter of <code>TriFunction</code> is the return type of the method to execute. Notice how this is omitted (inferred) in the lambda expression and the method reference.</li>
</ul>
<p>It may seem odd to just see the interface, the class and how they are used with a method reference, but this becomes more evident when you see the anonymous class or even the lambda version.</p>
<p>From:</p>
<p><code class="java hljs">(Sum s, String arg1, String arg2) -> s.doSum(arg1, arg2)</code></p>
<p>To</p>
<p><code class="java hljs">Sum::doSum</code></p>
<h2>Instance method of an existing object</h2>
<p>In this case, we have a lambda expression like the following:</p>
<p><code class="java hljs">(args) -> obj.instanceMethod(args)</code></p>
<p>That can be turned into the following method reference:</p>
<p><code class="java hljs">obj::instanceMethod</code></p>
<p>This time, an instance defined somewhere else is used, and the arguments (if any) are passed behind the curtains like in the <code>static</code> method case.</p>
<p>For example, assuming these classes:</p>
<p><code class="java hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Car</span></span> {<br />
<span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> id;<br />
<span class="hljs-keyword">private</span> String color;<br />
<span class="hljs-comment">// More properties<br /></span> <span class="hljs-comment">// And getter and setters<br /></span>}<br />
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Mechanic</span></span> {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">fix</span><span class="hljs-params">(Car c)</span></span> {<br />
System.out.println(<span class="hljs-string">"Fixing car "</span> + c.getId());<br />
}<br />
}</code></p>
<p>And this method:</p>
<p><code class="java hljs"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">execute</span><span class="hljs-params">(Car car, Consumer<Car> c)</span></span> {<br />
c.accept(car);<br />
}</code></p>
<p>We can call the above method using:</p>
<p><code class="java hljs"><span class="hljs-keyword">final</span> Mechanic mechanic = <span class="hljs-keyword">new</span> Mechanic();<br />
Car car = <span class="hljs-keyword">new</span> Car();<br />
<br />
<span class="hljs-comment">// Using an anonymous class</span><br />
execute(car, <span class="hljs-keyword">new</span> Consumer<Car>() {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">accept</span><span class="hljs-params">(Car c)</span></span> {<br />
mechanic.fix(c);<br />
}<br />
});<br />
<br />
<span class="hljs-comment">// Using a lambda expression</span><br />
execute(car, c -> mechanic.fix(c));<br />
<br />
<span class="hljs-comment">// Using a method reference</span><br />
execute(car, mechanic::fix);</code></p>
<p>The key, in this case, is to use any object visible by an anonymous class/lambda expression and pass some arguments to an instance method of that object.</p>
<p>Here's another quick example using another <code>Consumer</code>:</p>
<p><code class="java hljs">Consumer<String> c = System.out::println;<br />
c.accept(<span class="hljs-string">"Hello"</span>);</code></p>
<h2>Constructor</h2>
<p>In this case, we have a lambda expression like the following:</p>
<p><code class="java hljs">(args) -> <span class="hljs-keyword">new</span> ClassName(args)</code></p>
<p>That can be turned into the following method reference:</p>
<p><code class="java hljs">ClassName::<span class="hljs-keyword">new</span></code></p>
<p>The only thing this lambda expression does is to create a new object, so we just reference a constructor of the class with the keyword <code>new</code>. Like in the other cases, arguments (if any) are not passed in the method reference.</p>
<p>Most of the time, we can use this syntax with two (or three) interfaces of the <code>java.util.function</code> package.</p>
<p>If the constructor takes no arguments, a <code>Supplier</code> will do the job:</p>
<p><code class="java hljs"><span class="hljs-comment">// Using an anonymous class</span><br />
Supplier<List<String>> s = <span class="hljs-keyword">new</span> Supplier() {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> List<String> <span class="hljs-title">get</span><span class="hljs-params">()</span></span> {<br />
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ArrayList<String>();<br />
}<br />
};<br />
List<String> l = s.get();<br />
<br />
<span class="hljs-comment">// Using a lambda expression<br /></span>Supplier<List<String>> s = () -> <span class="hljs-keyword">new</span> ArrayList<String>();<br />
List<String> l = s.get();<br />
<br />
<span class="hljs-comment">// Using a method reference</span><br />
Supplier<List<String>> s = ArrayList::<span class="hljs-keyword">new</span>;<br />
List<String> l = s.get();</code></p>
<p>If the constructor takes an argument, we can use the <code>Function</code> interface. For example:</p>
<p><code class="java hljs"><span class="hljs-comment">// Using a anonymous class</span><br />
Function<String, Integer> f =<br />
<span class="hljs-keyword">new</span> Function<String, Integer>() {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> Integer <span class="hljs-title">apply</span><span class="hljs-params">(String s)</span></span> {<br />
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Integer(s);<br />
}<br />
};<br />
Integer i = f.apply(<span class="hljs-string">"100"</span>);<br />
<br />
<span class="hljs-comment">// Using a lambda expression</span><br />
Function<String, Integer> f = s -> <span class="hljs-keyword">new</span> Integer(s);<br />
Integer i = f.apply(<span class="hljs-string">"100"</span>);<br />
<br />
<span class="hljs-comment">// Using a method reference</span><br />
Function<String, Integer> f = Integer::<span class="hljs-keyword">new</span>;<br />
Integer i = f.apply(<span class="hljs-string">"100"</span>);</code></p>
<p>If the constructor takes two arguments, we use the <code>BiFunction</code> interface:</p>
<p><code class="java hljs"><span class="hljs-comment">// Using a anonymous class</span><br />
BiFunction<String, String, Locale> f = <span class="hljs-keyword">new</span> BiFunction<String, String, Locale>() {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> Locale <span class="hljs-title">apply</span><span class="hljs-params">(String lang, String country)</span></span> {<br />
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Locale(lang, country);<br />
}<br />
};<br />
Locale loc = f.apply(<span class="hljs-string">"en"</span>,<span class="hljs-string">"UK"</span>);<br />
<br />
<span class="hljs-comment">// Using a lambda expression</span><br />
BiFunction<String, String, Locale> f = (lang, country) -> <span class="hljs-keyword">new</span> Locale(lang, country);<br />
Locale loc = f.apply(<span class="hljs-string">"en"</span>,<span class="hljs-string">"UK"</span>);<br />
<br />
<span class="hljs-comment">// Using a method reference</span><br />
BiFunction<String, String, Locale> f = Locale::<span class="hljs-keyword">new</span>;<br />
Locale loc = f.apply(<span class="hljs-string">"en"</span>,<span class="hljs-string">"UK"</span>);</code></p>
<p>If you have a constructor with three or more arguments, you would have to create your own functional interface.</p>
<p>You can see that referencing a constructor is very similar to referencing a static method. The difference is that the constructor "method name" is <code>new</code>.</p>
<p>Many of the examples of this chapter are very simple and probably they don't justify the use of lambda expressions or method references.</p>
<p>As mentioned at the beginning of the chapter, use method reference if they make your code <b>CLEARER</b>.</p>
<p>You can avoid the one method restriction by grouping all your code in a static method, for example, and create a reference to that method instead of using a class or a lambda expression with many lines.</p>
<p>But the real power of lambda expressions and method references comes when they are combined with another new feature of Java 8 – streams.</p>
<p>That will be the topic of the next section.</p>
<div style="page-break-after:always;"></div>
<h2>Key Points</h2>
<ul>
<li>A method reference is the shorthand syntax to a lambda expression that executes just one method.</li>
<li>The syntax of a method reference is:<br />
<code class="java hljs">ObjectOrClassName :: methodName</code></li>
<li>In a method reference, you place the object (or class) that contains the method before the <code>::</code> operator and the name of the method after it without arguments.</li>
<li>There are four types of method references:
<ul>
<li>A method reference to a <code>static</code> method</li>
<li>A method reference to an instance method of an object of a particular type</li>
<li>A method reference to an instance method of an existing object</li>
<li>A method reference to a constructor</li>
</ul>
</li>
<li>For static methods, we have a lambda expression like the following:<br />
<code class="java hljs">(args) -> Class.staticMethod(args)</code></li>
<li>That can be turned into the following method reference: <code class="java hljs">Class::staticMethod</code></li>
<li>For instance methods of objects of a particular type, we have a lambda expression like the following:<br />
<code class="java hljs">(obj, args) -> obj.instanceMethod(args)</code></li>
<li>Where an instance of an object is passed as an argument and one of its methods is executed with some optional(s) parameter(s).</li>
<li>And that can be turned into the following method reference:<br />
<code class="java hljs">ObjectType::instanceMethod</code></li>
<li>For instance methods of existing objects, we have a lambda expression like the following:<br />
<code class="java hljs">(args) -> obj.instanceMethod(args)</code></li>
<li>That can be turned into the following method reference:<br />
<code class="java hljs">obj::instanceMethod</code></li>
<li>For creating objects (calling a constructor), we have a lambda expression like the following:<br />
<code class="java hljs">(args) -> <span class="hljs-keyword">new</span> ClassName(args)</code></li>
<li>That can be turned into the following method reference: <code class="java hljs">ClassName::<span class="hljs-keyword">new</span></code></li>
</ul>
<div style="page-break-after:always;"></div>
<h2>Self Test</h2>
<p>1. Given:</p>
<p><code class="java hljs"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Question_11_1</span></span> {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Runnable <span class="hljs-title">print</span><span class="hljs-params">()</span></span> {<br />
<span class="hljs-keyword">return</span> () -> {<br />
System.out.println(<span class="hljs-string">"Hi"</span>);<br />
};<br />
}<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span></span> {<br />
Runnable r = Question_11_1::print;<br />
r.run();<br />
}<br />
}</code></p>
<p>What is the result?<br /> A. <code>Hi</code><br /> B. Nothing is printed<br /> C. Compilation fails<br /> D. An exception occurs at runtime</p>
<div style="page-break-after:always;"></div>
<p>2. Given:</p>
<p><code class="java hljs"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Question_11_2</span></span> {<br />
<span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">print</span><span class="hljs-params">()</span></span> {<br />
System.out.println(<span class="hljs-string">"Hi"</span>);<br />
}<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span></span> {<br />
Consumer<Question_11_2> c =<br />
Question_11_2::print;<br />
c.accept(<span class="hljs-keyword">new</span> Question_11_2());<br />
}<br />
}</code></p>
<p>What is the result?<br /> A. <code>Hi</code><br /> B. Nothing is printed<br /> C. Compilation fails<br /> D. An exception occurs at runtime</p>
<div style="page-break-after:always;"></div>
<p>3. Which of the following statements is true?<br /> A. You can have a method reference of a constructor.<br /> B. Method references replace any lambda expression.<br /> C. When using method references, you don’t have to specify the arguments the method receives.<br /> D. The <code>::</code> operator can be also used in lambda expressions.</p>
<div style="page-break-after:always;"></div>
<p>4. Given:</p>
<p><code class="java hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Car</span></span> {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drive</span><span class="hljs-params">(<span class="hljs-keyword">int</span> speed)</span></span> {<br />
<span class="hljs-comment">//...<br /></span> }<br />
}</code></p>
<p>And:</p>
<p><code class="java hljs">Car c = <span class="hljs-keyword">new</span> Car();<br />
IntConsumer consumer = (<span class="hljs-keyword">int</span> speed) -> c.drive(speed);</code></p>
<p>Which of the following method references can replace the above lambda expression?<br /> A. <code>Car.drive</code><br /> B. <code>c.drive(speed)</code><br /> C. <code>Car::drive</code><br /> D. <code>c::drive</code></p>
<div style="page-break-after:always;"></div>
<p>5. Given:</p>
<p><code class="java hljs"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Question_11_5</span></span> {<br />
Question_11_5() {<br />
System.out.println(<span class="hljs-number">0</span>);<br />
}<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span></span> {<br />
Runnable r = Question_11_5::<span class="hljs-keyword">new</span>;<br />
}<br />
}</code></p>
<p>What is the result?<br /> A. <code>0</code><br /> B. Nothing is printed<br /> C. Compilation fails<br /> D. An exception occurs at runtime</p>
<div style="page-break-after:always;"></div>
<p>6. Given:</p>
<p><code class="java hljs"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Test</span></span> {<br />
Test() {<br />
System.out.println(<span class="hljs-number">0</span>);<br />
}<br />
Test(String s) {<br />
System.out.println(<span class="hljs-number">1</span>);<br />
}<br />
}<br />
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Question_11_6</span></span> {<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span></span> {<br />
BiFunction<String, String, Test> f = Test::<span class="hljs-keyword">new</span>;<br />
f.apply(<span class="hljs-keyword">null</span>, <span class="hljs-keyword">null</span>);<br />
}<br />
}</code></p>
<p>What is the result?<br /> A. <code>0</code><br /> B. <code>1</code><br /> C. Nothing is printed<br /> D. Compilation fails<br /> E. An exception occurs at runtime</p>
<div style="page-break-after:always;"></div>
<p>7. Given:</p>
<p><code class="java hljs"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Question_11_7</span></span> {<br />
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">Question_11_7</span><span class="hljs-params">()</span></span> {}<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Question_11_7 <span class="hljs-title">create</span><span class="hljs-params">()</span></span> {<br />
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Question_11_7();<br />
}<br />
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String args[])</span></span> {<br />
<span class="hljs-comment">// 1<br /></span> }<br />
}</code></p>
<p>Which of the following method references can be used to get instances of class <code>Question_11_7</code> at line <code>// 1</code>?<br /> A.
<br /></p>
<p><code class="java hljs">Supplier<Question_11_7> s = Question_11_7::<span class="hljs-keyword">new</span>;</code></p>
<p><br /> B.
<br /></p>
<p><code class="java hljs">UnaryOperator<Question_11_7> u = Question_11_7::create;</code></p>
<p><br /> C.
<br /></p>
<p><code class="java hljs">Consumer<Question_11_7> c = Question_11_7::create;</code></p>
<p><br /> D.
<br /></p>
<p><code class="java hljs">Supplier<Question_11_7> s = Question_11_7::create;</code></p>
<div class="answers">
<a href="ch11a.html" target="_blank">Open answers page</a>
</div>
<div class="book-info"></div>
<div class="linkbox">
<div class="previous">
<a href="ch10.html">10. Java Built-In Lambda Interfaces</a>
</div>
<div class="next">
<a href="ch12.html">12. Stream</a>
</div>
<div style="clear:both;"></div>
</div>
</div>
</div>
</body>
</html>