March 2021 Book Update

See notes in "Foreword to the Leanpub Edition"
This commit is contained in:
Bruce Eckel 2021-03-04 16:15:04 -07:00
parent 129df0b752
commit ede3954d86
155 changed files with 1861 additions and 1222 deletions

View File

@ -33,7 +33,7 @@ class ReversibleArrayList<T> extends ArrayList<T> {
public class AdapterMethodIdiom { public class AdapterMethodIdiom {
public static void main(String[] args) { public static void main(String[] args) {
ReversibleArrayList<String> ral = ReversibleArrayList<String> ral =
new ReversibleArrayList<String>( new ReversibleArrayList<>(
Arrays.asList("To be or not to be".split(" "))); Arrays.asList("To be or not to be".split(" ")));
// Grabs the ordinary iterator via iterator(): // Grabs the ordinary iterator via iterator():
for(String s : ral) for(String s : ral)

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
public class CollectionSequence public class CollectionSequence

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
public class CrossCollectionIteration { public class CrossCollectionIteration {

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
public class CrossCollectionIteration2 { public class CrossCollectionIteration2 {

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
public class InterfaceVsIterator { public class InterfaceVsIterator {

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
public class LinkedListFeatures { public class LinkedListFeatures {

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
public class ListFeatures { public class ListFeatures {

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
public class ListIteration { public class ListIteration {

View File

@ -4,7 +4,7 @@
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// {java collections.MapOfList} // {java collections.MapOfList}
package collections; package collections;
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
public class MapOfList { public class MapOfList {

View File

@ -29,7 +29,7 @@ public class MultiIterableClass extends IterableClass {
return new Iterable<String>() { return new Iterable<String>() {
public Iterator<String> iterator() { public Iterator<String> iterator() {
List<String> shuffled = List<String> shuffled =
new ArrayList<String>(Arrays.asList(words)); new ArrayList<>(Arrays.asList(words));
Collections.shuffle(shuffled, new Random(47)); Collections.shuffle(shuffled, new Random(47));
return shuffled.iterator(); return shuffled.iterator();
} }

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
class PetSequence { class PetSequence {

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
public class PetMap { public class PetMap {

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
public class SimpleIteration { public class SimpleIteration {

View File

@ -56,8 +56,7 @@ public class CollectionMethods {
// c2 and c3 (an intersection of sets): // c2 and c3 (an intersection of sets):
c2.retainAll(c3); c2.retainAll(c3);
show(c2); show(c2);
// Throw away all the elements // Discard all c2 elements that also appear in c3:
// in c2 that also appear in c3:
c2.removeAll(c3); c2.removeAll(c3);
System.out.println( System.out.println(
"c2.isEmpty() = " + c2.isEmpty()); "c2.isEmpty() = " + c2.isEmpty());

View File

@ -1,12 +1,512 @@
0: ForkJoinPool.commonPool-worker-1
0: main 0: main
1: main 2: main
1: ForkJoinPool.commonPool-worker-3 2: ForkJoinPool.commonPool-worker-1
1: ForkJoinPool.commonPool-worker-5
3: ForkJoinPool.commonPool-worker-5
3: main 3: main
5: ForkJoinPool.commonPool-worker-5 4: ForkJoinPool.commonPool-worker-1
5: main 5: main
7: ForkJoinPool.commonPool-worker-5 6: ForkJoinPool.commonPool-worker-1
8: main 7: main
8: ForkJoinPool.commonPool-worker-3 9: ForkJoinPool.commonPool-worker-1
10: ForkJoinPool.commonPool-worker-5 9: main
11: ForkJoinPool.commonPool-worker-1
11: main
12: ForkJoinPool.commonPool-worker-1
13: main
15: ForkJoinPool.commonPool-worker-1
15: main
17: main
18: main
19: main
20: main
21: main
17: ForkJoinPool.commonPool-worker-1
23: main
23: ForkJoinPool.commonPool-worker-1
24: main
25: ForkJoinPool.commonPool-worker-1
26: main
27: ForkJoinPool.commonPool-worker-1
28: main
29: ForkJoinPool.commonPool-worker-1
30: main
32: main
32: ForkJoinPool.commonPool-worker-1
33: main
35: ForkJoinPool.commonPool-worker-1
36: ForkJoinPool.commonPool-worker-1
37: ForkJoinPool.commonPool-worker-1
38: ForkJoinPool.commonPool-worker-1
35: main
39: ForkJoinPool.commonPool-worker-1
41: ForkJoinPool.commonPool-worker-1
40: main
42: ForkJoinPool.commonPool-worker-1
43: main
44: ForkJoinPool.commonPool-worker-1
45: main
46: ForkJoinPool.commonPool-worker-1
47: main
49: main
50: main
50: ForkJoinPool.commonPool-worker-1
51: main
52: ForkJoinPool.commonPool-worker-1
53: main
55: ForkJoinPool.commonPool-worker-1
55: main
56: ForkJoinPool.commonPool-worker-1
58: ForkJoinPool.commonPool-worker-1
57: main
59: ForkJoinPool.commonPool-worker-1
60: main
61: ForkJoinPool.commonPool-worker-1
62: main
63: ForkJoinPool.commonPool-worker-1
64: main
65: ForkJoinPool.commonPool-worker-1
66: main
67: ForkJoinPool.commonPool-worker-1
68: main
69: ForkJoinPool.commonPool-worker-1
71: ForkJoinPool.commonPool-worker-1
72: ForkJoinPool.commonPool-worker-1
70: main
73: ForkJoinPool.commonPool-worker-1
75: ForkJoinPool.commonPool-worker-1
76: ForkJoinPool.commonPool-worker-1
74: main
77: ForkJoinPool.commonPool-worker-1
78: ForkJoinPool.commonPool-worker-1
79: main
80: ForkJoinPool.commonPool-worker-1
81: main
82: ForkJoinPool.commonPool-worker-1
83: main
84: ForkJoinPool.commonPool-worker-1
85: main
86: ForkJoinPool.commonPool-worker-1
87: main
89: ForkJoinPool.commonPool-worker-1
90: ForkJoinPool.commonPool-worker-1
89: main
91: ForkJoinPool.commonPool-worker-1
92: main
93: ForkJoinPool.commonPool-worker-1
94: main
95: ForkJoinPool.commonPool-worker-1
96: main
98: main
97: ForkJoinPool.commonPool-worker-1
99: main
100: ForkJoinPool.commonPool-worker-1
101: main
103: ForkJoinPool.commonPool-worker-1
103: main
104: ForkJoinPool.commonPool-worker-1
106: ForkJoinPool.commonPool-worker-1
107: ForkJoinPool.commonPool-worker-1
106: main
108: ForkJoinPool.commonPool-worker-1
110: ForkJoinPool.commonPool-worker-1
108: ForkJoinPool.commonPool-worker-2
111: ForkJoinPool.commonPool-worker-1
110: main
113: ForkJoinPool.commonPool-worker-1
112: ForkJoinPool.commonPool-worker-2
115: ForkJoinPool.commonPool-worker-1
116: main
116: ForkJoinPool.commonPool-worker-2
117: ForkJoinPool.commonPool-worker-1
118: main
119: ForkJoinPool.commonPool-worker-2
120: ForkJoinPool.commonPool-worker-1
121: main
123: ForkJoinPool.commonPool-worker-1
124: main
124: ForkJoinPool.commonPool-worker-2
126: main
126: ForkJoinPool.commonPool-worker-1
127: ForkJoinPool.commonPool-worker-2
128: main
130: ForkJoinPool.commonPool-worker-1
130: ForkJoinPool.commonPool-worker-2
131: main
133: ForkJoinPool.commonPool-worker-1
134: ForkJoinPool.commonPool-worker-2
134: main
136: ForkJoinPool.commonPool-worker-1
137: main
137: ForkJoinPool.commonPool-worker-2
138: ForkJoinPool.commonPool-worker-1
140: main
140: ForkJoinPool.commonPool-worker-2
141: ForkJoinPool.commonPool-worker-1
143: main
143: ForkJoinPool.commonPool-worker-2
145: ForkJoinPool.commonPool-worker-1
146: main
146: ForkJoinPool.commonPool-worker-2
148: ForkJoinPool.commonPool-worker-1
149: main
149: ForkJoinPool.commonPool-worker-2
151: ForkJoinPool.commonPool-worker-1
152: ForkJoinPool.commonPool-worker-2
154: ForkJoinPool.commonPool-worker-1
154: ForkJoinPool.commonPool-worker-2
152: main
156: ForkJoinPool.commonPool-worker-1
156: ForkJoinPool.commonPool-worker-2
159: ForkJoinPool.commonPool-worker-1
159: ForkJoinPool.commonPool-worker-2
161: ForkJoinPool.commonPool-worker-1
159: main
162: ForkJoinPool.commonPool-worker-1
161: ForkJoinPool.commonPool-worker-2
164: ForkJoinPool.commonPool-worker-1
163: main
166: ForkJoinPool.commonPool-worker-1
168: ForkJoinPool.commonPool-worker-1
168: main
169: ForkJoinPool.commonPool-worker-1
170: main
167: ForkJoinPool.commonPool-worker-2
171: ForkJoinPool.commonPool-worker-1
172: main
168: ForkJoinPool.commonPool-worker-3
174: ForkJoinPool.commonPool-worker-1
175: main
178: ForkJoinPool.commonPool-worker-1
178: main
178: ForkJoinPool.commonPool-worker-3
175: ForkJoinPool.commonPool-worker-2
179: ForkJoinPool.commonPool-worker-1
181: main
183: ForkJoinPool.commonPool-worker-1
183: ForkJoinPool.commonPool-worker-2
184: main
184: ForkJoinPool.commonPool-worker-3
185: ForkJoinPool.commonPool-worker-1
187: main
187: ForkJoinPool.commonPool-worker-2
189: ForkJoinPool.commonPool-worker-1
191: main
189: ForkJoinPool.commonPool-worker-3
191: ForkJoinPool.commonPool-worker-2
193: main
193: ForkJoinPool.commonPool-worker-1
195: ForkJoinPool.commonPool-worker-3
195: ForkJoinPool.commonPool-worker-2
197: main
199: ForkJoinPool.commonPool-worker-3
199: ForkJoinPool.commonPool-worker-2
197: ForkJoinPool.commonPool-worker-1
200: main
202: ForkJoinPool.commonPool-worker-3
203: ForkJoinPool.commonPool-worker-2
204: ForkJoinPool.commonPool-worker-1
204: main
205: ForkJoinPool.commonPool-worker-3
207: ForkJoinPool.commonPool-worker-2
208: ForkJoinPool.commonPool-worker-1
208: main
209: ForkJoinPool.commonPool-worker-3
211: ForkJoinPool.commonPool-worker-2
211: ForkJoinPool.commonPool-worker-1
213: main
213: ForkJoinPool.commonPool-worker-3
215: ForkJoinPool.commonPool-worker-2
215: ForkJoinPool.commonPool-worker-1
217: main
217: ForkJoinPool.commonPool-worker-3
219: ForkJoinPool.commonPool-worker-2
220: ForkJoinPool.commonPool-worker-1
221: main
221: ForkJoinPool.commonPool-worker-3
224: ForkJoinPool.commonPool-worker-1
225: main
225: ForkJoinPool.commonPool-worker-3
223: ForkJoinPool.commonPool-worker-2
227: ForkJoinPool.commonPool-worker-1
227: main
229: ForkJoinPool.commonPool-worker-3
229: ForkJoinPool.commonPool-worker-2
231: ForkJoinPool.commonPool-worker-1
231: main
233: ForkJoinPool.commonPool-worker-3
233: ForkJoinPool.commonPool-worker-2
235: ForkJoinPool.commonPool-worker-1
236: main
237: ForkJoinPool.commonPool-worker-3
237: ForkJoinPool.commonPool-worker-2
239: ForkJoinPool.commonPool-worker-1
241: main
241: ForkJoinPool.commonPool-worker-2
241: ForkJoinPool.commonPool-worker-3
243: ForkJoinPool.commonPool-worker-1
244: main
244: ForkJoinPool.commonPool-worker-2
245: ForkJoinPool.commonPool-worker-3
247: ForkJoinPool.commonPool-worker-1
249: ForkJoinPool.commonPool-worker-3
251: ForkJoinPool.commonPool-worker-3
250: ForkJoinPool.commonPool-worker-1
251: ForkJoinPool.commonPool-worker-2
253: ForkJoinPool.commonPool-worker-3
254: ForkJoinPool.commonPool-worker-1
254: ForkJoinPool.commonPool-worker-2
251: main
255: ForkJoinPool.commonPool-worker-3
257: ForkJoinPool.commonPool-worker-1
257: ForkJoinPool.commonPool-worker-2
259: ForkJoinPool.commonPool-worker-3
261: ForkJoinPool.commonPool-worker-1
261: ForkJoinPool.commonPool-worker-2
262: ForkJoinPool.commonPool-worker-3
263: ForkJoinPool.commonPool-worker-1
264: ForkJoinPool.commonPool-worker-2
265: ForkJoinPool.commonPool-worker-3
267: ForkJoinPool.commonPool-worker-1
267: ForkJoinPool.commonPool-worker-2
261: main
268: ForkJoinPool.commonPool-worker-3
269: ForkJoinPool.commonPool-worker-1
270: ForkJoinPool.commonPool-worker-2
272: ForkJoinPool.commonPool-worker-3
273: ForkJoinPool.commonPool-worker-1
276: ForkJoinPool.commonPool-worker-3
276: ForkJoinPool.commonPool-worker-1
274: ForkJoinPool.commonPool-worker-2
277: ForkJoinPool.commonPool-worker-3
279: ForkJoinPool.commonPool-worker-1
279: ForkJoinPool.commonPool-worker-2
275: main
281: ForkJoinPool.commonPool-worker-1
280: ForkJoinPool.commonPool-worker-3
282: ForkJoinPool.commonPool-worker-2
285: ForkJoinPool.commonPool-worker-1
286: ForkJoinPool.commonPool-worker-3
286: ForkJoinPool.commonPool-worker-2
288: ForkJoinPool.commonPool-worker-1
289: ForkJoinPool.commonPool-worker-3
289: ForkJoinPool.commonPool-worker-2
286: main
291: ForkJoinPool.commonPool-worker-1
292: ForkJoinPool.commonPool-worker-3
293: ForkJoinPool.commonPool-worker-2
293: main
296: ForkJoinPool.commonPool-worker-3
296: ForkJoinPool.commonPool-worker-2
297: main
297: ForkJoinPool.commonPool-worker-1
299: ForkJoinPool.commonPool-worker-3
299: ForkJoinPool.commonPool-worker-2
301: main
301: ForkJoinPool.commonPool-worker-1
303: ForkJoinPool.commonPool-worker-3
303: ForkJoinPool.commonPool-worker-2
305: main
305: ForkJoinPool.commonPool-worker-1
307: ForkJoinPool.commonPool-worker-3
307: ForkJoinPool.commonPool-worker-2
309: main
309: ForkJoinPool.commonPool-worker-1
311: ForkJoinPool.commonPool-worker-3
311: ForkJoinPool.commonPool-worker-2
313: main
313: ForkJoinPool.commonPool-worker-1
315: ForkJoinPool.commonPool-worker-3
315: ForkJoinPool.commonPool-worker-2
317: ForkJoinPool.commonPool-worker-1
319: ForkJoinPool.commonPool-worker-3
319: ForkJoinPool.commonPool-worker-2
320: ForkJoinPool.commonPool-worker-1
322: ForkJoinPool.commonPool-worker-3
317: main
323: ForkJoinPool.commonPool-worker-1
322: ForkJoinPool.commonPool-worker-2
324: ForkJoinPool.commonPool-worker-3
328: main
328: ForkJoinPool.commonPool-worker-3
328: ForkJoinPool.commonPool-worker-2
330: ForkJoinPool.commonPool-worker-3
329: main
331: ForkJoinPool.commonPool-worker-2
332: ForkJoinPool.commonPool-worker-3
334: ForkJoinPool.commonPool-worker-2
335: main
335: ForkJoinPool.commonPool-worker-3
337: ForkJoinPool.commonPool-worker-2
338: main
338: ForkJoinPool.commonPool-worker-3
340: ForkJoinPool.commonPool-worker-2
341: main
341: ForkJoinPool.commonPool-worker-3
343: ForkJoinPool.commonPool-worker-2
343: main
344: ForkJoinPool.commonPool-worker-3
346: ForkJoinPool.commonPool-worker-2
347: main
347: ForkJoinPool.commonPool-worker-3
349: ForkJoinPool.commonPool-worker-2
350: main
350: ForkJoinPool.commonPool-worker-3
351: ForkJoinPool.commonPool-worker-2
353: main
353: ForkJoinPool.commonPool-worker-3
355: ForkJoinPool.commonPool-worker-2
356: main
356: ForkJoinPool.commonPool-worker-3
358: ForkJoinPool.commonPool-worker-2
359: main
359: ForkJoinPool.commonPool-worker-3
361: ForkJoinPool.commonPool-worker-2
362: main
362: ForkJoinPool.commonPool-worker-3
365: main
364: ForkJoinPool.commonPool-worker-2
365: ForkJoinPool.commonPool-worker-3
366: main
368: ForkJoinPool.commonPool-worker-2
369: main
369: ForkJoinPool.commonPool-worker-3
372: ForkJoinPool.commonPool-worker-3
371: ForkJoinPool.commonPool-worker-2
372: main
374: ForkJoinPool.commonPool-worker-3
374: ForkJoinPool.commonPool-worker-2
376: ForkJoinPool.commonPool-worker-3
377: ForkJoinPool.commonPool-worker-2
378: ForkJoinPool.commonPool-worker-3
376: main
379: ForkJoinPool.commonPool-worker-2
380: ForkJoinPool.commonPool-worker-3
382: ForkJoinPool.commonPool-worker-2
383: ForkJoinPool.commonPool-worker-3
384: ForkJoinPool.commonPool-worker-2
385: ForkJoinPool.commonPool-worker-3
383: main
386: ForkJoinPool.commonPool-worker-2
387: ForkJoinPool.commonPool-worker-3
390: ForkJoinPool.commonPool-worker-2
390: ForkJoinPool.commonPool-worker-3
392: ForkJoinPool.commonPool-worker-2
392: ForkJoinPool.commonPool-worker-3
390: main
394: ForkJoinPool.commonPool-worker-2
394: ForkJoinPool.commonPool-worker-3
397: ForkJoinPool.commonPool-worker-2
397: ForkJoinPool.commonPool-worker-3
399: ForkJoinPool.commonPool-worker-2
397: main
400: ForkJoinPool.commonPool-worker-3
401: ForkJoinPool.commonPool-worker-3
401: ForkJoinPool.commonPool-worker-2
404: ForkJoinPool.commonPool-worker-3
404: ForkJoinPool.commonPool-worker-2
403: main
406: ForkJoinPool.commonPool-worker-3
406: ForkJoinPool.commonPool-worker-2
408: main
409: ForkJoinPool.commonPool-worker-3
409: ForkJoinPool.commonPool-worker-2
411: main
412: ForkJoinPool.commonPool-worker-3
412: ForkJoinPool.commonPool-worker-2
414: main
414: ForkJoinPool.commonPool-worker-3
415: ForkJoinPool.commonPool-worker-2
418: ForkJoinPool.commonPool-worker-3
418: ForkJoinPool.commonPool-worker-2
419: ForkJoinPool.commonPool-worker-3
420: ForkJoinPool.commonPool-worker-2
421: ForkJoinPool.commonPool-worker-3
422: ForkJoinPool.commonPool-worker-2
423: ForkJoinPool.commonPool-worker-3
424: ForkJoinPool.commonPool-worker-2
425: ForkJoinPool.commonPool-worker-3
426: ForkJoinPool.commonPool-worker-2
427: ForkJoinPool.commonPool-worker-3
428: ForkJoinPool.commonPool-worker-2
430: ForkJoinPool.commonPool-worker-2
430: ForkJoinPool.commonPool-worker-3
432: ForkJoinPool.commonPool-worker-3
432: ForkJoinPool.commonPool-worker-2
433: ForkJoinPool.commonPool-worker-3
434: ForkJoinPool.commonPool-worker-2
435: ForkJoinPool.commonPool-worker-3
436: ForkJoinPool.commonPool-worker-2
437: ForkJoinPool.commonPool-worker-3
438: ForkJoinPool.commonPool-worker-2
439: ForkJoinPool.commonPool-worker-3
440: ForkJoinPool.commonPool-worker-2
441: ForkJoinPool.commonPool-worker-3
442: ForkJoinPool.commonPool-worker-2
443: ForkJoinPool.commonPool-worker-3
444: ForkJoinPool.commonPool-worker-2
445: ForkJoinPool.commonPool-worker-3
446: ForkJoinPool.commonPool-worker-2
447: ForkJoinPool.commonPool-worker-3
448: ForkJoinPool.commonPool-worker-2
449: ForkJoinPool.commonPool-worker-3
450: ForkJoinPool.commonPool-worker-2
451: ForkJoinPool.commonPool-worker-3
452: ForkJoinPool.commonPool-worker-2
453: ForkJoinPool.commonPool-worker-3
454: ForkJoinPool.commonPool-worker-2
456: ForkJoinPool.commonPool-worker-2
455: ForkJoinPool.commonPool-worker-3
458: ForkJoinPool.commonPool-worker-3
457: ForkJoinPool.commonPool-worker-2
459: ForkJoinPool.commonPool-worker-3
460: ForkJoinPool.commonPool-worker-2
461: ForkJoinPool.commonPool-worker-3
462: ForkJoinPool.commonPool-worker-2
463: ForkJoinPool.commonPool-worker-3
464: ForkJoinPool.commonPool-worker-2
465: ForkJoinPool.commonPool-worker-3
466: ForkJoinPool.commonPool-worker-2
467: ForkJoinPool.commonPool-worker-3
468: ForkJoinPool.commonPool-worker-2
469: ForkJoinPool.commonPool-worker-3
470: ForkJoinPool.commonPool-worker-2
471: ForkJoinPool.commonPool-worker-3
472: ForkJoinPool.commonPool-worker-2
473: ForkJoinPool.commonPool-worker-3
474: ForkJoinPool.commonPool-worker-2
475: ForkJoinPool.commonPool-worker-3
476: ForkJoinPool.commonPool-worker-2
477: ForkJoinPool.commonPool-worker-3
478: ForkJoinPool.commonPool-worker-2
479: ForkJoinPool.commonPool-worker-3
480: ForkJoinPool.commonPool-worker-2
482: ForkJoinPool.commonPool-worker-2
481: ForkJoinPool.commonPool-worker-3
484: ForkJoinPool.commonPool-worker-3
484: ForkJoinPool.commonPool-worker-2
327: ForkJoinPool.commonPool-worker-1
485: ForkJoinPool.commonPool-worker-3
486: ForkJoinPool.commonPool-worker-2
488: ForkJoinPool.commonPool-worker-3
488: ForkJoinPool.commonPool-worker-1
489: ForkJoinPool.commonPool-worker-2
490: ForkJoinPool.commonPool-worker-3
491: ForkJoinPool.commonPool-worker-1
492: ForkJoinPool.commonPool-worker-2
495: ForkJoinPool.commonPool-worker-2
493: ForkJoinPool.commonPool-worker-3
496: ForkJoinPool.commonPool-worker-2
497: ForkJoinPool.commonPool-worker-3
499: ForkJoinPool.commonPool-worker-3
500: ForkJoinPool.commonPool-worker-3
501: ForkJoinPool.commonPool-worker-3
502: ForkJoinPool.commonPool-worker-3
503: ForkJoinPool.commonPool-worker-3
504: ForkJoinPool.commonPool-worker-3
505: ForkJoinPool.commonPool-worker-3
506: ForkJoinPool.commonPool-worker-3
507: ForkJoinPool.commonPool-worker-3
508: ForkJoinPool.commonPool-worker-3
509: ForkJoinPool.commonPool-worker-3
510: ForkJoinPool.commonPool-worker-3
511: ForkJoinPool.commonPool-worker-3

View File

@ -26,7 +26,7 @@ class Mail {
public String details() { public String details() {
return toString() + return toString() +
", General Delivery: " + generalDelivery + ", General Delivery: " + generalDelivery +
", Address Scanability: " + scannability + ", Address Scannability: " + scannability +
", Address Readability: " + readability + ", Address Readability: " + readability +
", Address Address: " + address + ", Address Address: " + address +
", Return address: " + returnAddress; ", Return address: " + returnAddress;
@ -138,52 +138,52 @@ public class PostOffice {
} }
} }
/* Output: /* Output:
Mail 0, General Delivery: NO2, Address Scanability: Mail 0, General Delivery: NO2, Address Scannability:
UNSCANNABLE, Address Readability: YES3, Address UNSCANNABLE, Address Readability: YES3, Address
Address: OK1, Return address: OK1 Address: OK1, Return address: OK1
Delivering Mail 0 normally Delivering Mail 0 normally
***** *****
Mail 1, General Delivery: NO5, Address Scanability: Mail 1, General Delivery: NO5, Address Scannability:
YES3, Address Readability: ILLEGIBLE, Address Address: YES3, Address Readability: ILLEGIBLE, Address Address:
OK5, Return address: OK1 OK5, Return address: OK1
Delivering Mail 1 automatically Delivering Mail 1 automatically
***** *****
Mail 2, General Delivery: YES, Address Scanability: Mail 2, General Delivery: YES, Address Scannability:
YES3, Address Readability: YES1, Address Address: OK1, YES3, Address Readability: YES1, Address Address: OK1,
Return address: OK5 Return address: OK5
Using general delivery for Mail 2 Using general delivery for Mail 2
***** *****
Mail 3, General Delivery: NO4, Address Scanability: Mail 3, General Delivery: NO4, Address Scannability:
YES3, Address Readability: YES1, Address Address: YES3, Address Readability: YES1, Address Address:
INCORRECT, Return address: OK4 INCORRECT, Return address: OK4
Returning Mail 3 to sender Returning Mail 3 to sender
***** *****
Mail 4, General Delivery: NO4, Address Scanability: Mail 4, General Delivery: NO4, Address Scannability:
UNSCANNABLE, Address Readability: YES1, Address UNSCANNABLE, Address Readability: YES1, Address
Address: INCORRECT, Return address: OK2 Address: INCORRECT, Return address: OK2
Returning Mail 4 to sender Returning Mail 4 to sender
***** *****
Mail 5, General Delivery: NO3, Address Scanability: Mail 5, General Delivery: NO3, Address Scannability:
YES1, Address Readability: ILLEGIBLE, Address Address: YES1, Address Readability: ILLEGIBLE, Address Address:
OK4, Return address: OK2 OK4, Return address: OK2
Delivering Mail 5 automatically Delivering Mail 5 automatically
***** *****
Mail 6, General Delivery: YES, Address Scanability: Mail 6, General Delivery: YES, Address Scannability:
YES4, Address Readability: ILLEGIBLE, Address Address: YES4, Address Readability: ILLEGIBLE, Address Address:
OK4, Return address: OK4 OK4, Return address: OK4
Using general delivery for Mail 6 Using general delivery for Mail 6
***** *****
Mail 7, General Delivery: YES, Address Scanability: Mail 7, General Delivery: YES, Address Scannability:
YES3, Address Readability: YES4, Address Address: OK2, YES3, Address Readability: YES4, Address Address: OK2,
Return address: MISSING Return address: MISSING
Using general delivery for Mail 7 Using general delivery for Mail 7
***** *****
Mail 8, General Delivery: NO3, Address Scanability: Mail 8, General Delivery: NO3, Address Scannability:
YES1, Address Readability: YES3, Address Address: YES1, Address Readability: YES3, Address Address:
INCORRECT, Return address: MISSING INCORRECT, Return address: MISSING
Mail 8 is a dead letter Mail 8 is a dead letter
***** *****
Mail 9, General Delivery: NO1, Address Scanability: Mail 9, General Delivery: NO1, Address Scannability:
UNSCANNABLE, Address Readability: YES2, Address UNSCANNABLE, Address Readability: YES2, Address
Address: OK1, Return address: OK4 Address: OK1, Return address: OK4
Delivering Mail 9 normally Delivering Mail 9 normally

View File

@ -11,7 +11,7 @@ public interface Food {
} }
enum MainCourse implements Food { enum MainCourse implements Food {
LASAGNE, BURRITO, PAD_THAI, LASAGNE, BURRITO, PAD_THAI,
LENTILS, HUMMOUS, VINDALOO; LENTILS, HUMMUS, VINDALOO;
} }
enum Dessert implements Food { enum Dessert implements Food {
TIRAMISU, GELATO, BLACK_FOREST_CAKE, TIRAMISU, GELATO, BLACK_FOREST_CAKE,

View File

@ -21,7 +21,7 @@ public enum Meal2 {
} }
enum MainCourse implements Food { enum MainCourse implements Food {
LASAGNE, BURRITO, PAD_THAI, LASAGNE, BURRITO, PAD_THAI,
LENTILS, HUMMOUS, VINDALOO; LENTILS, HUMMUS, VINDALOO;
} }
enum Dessert implements Food { enum Dessert implements Food {
TIRAMISU, GELATO, BLACK_FOREST_CAKE, TIRAMISU, GELATO, BLACK_FOREST_CAKE,

View File

@ -3,7 +3,7 @@
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
import collections.MapOfList; import collections.MapOfList;
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
public class IndividualTest { public class IndividualTest {

View File

@ -3,7 +3,7 @@
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Using Collection.checkedList() // Using Collection.checkedList()
import typeinfo.pets.*; import reflection.pets.*;
import java.util.*; import java.util.*;
public class CheckedList { public class CheckedList {
@ -30,6 +30,6 @@ public class CheckedList {
} }
/* Output: /* Output:
Expected: java.lang.ClassCastException: Attempt to Expected: java.lang.ClassCastException: Attempt to
insert class typeinfo.pets.Cat element into collection insert class reflection.pets.Cat element into collection
with element type class typeinfo.pets.Dog with element type class reflection.pets.Dog
*/ */

View File

@ -3,7 +3,7 @@
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// "Assisted Latent Typing" // "Assisted Latent Typing"
import typeinfo.pets.*; import reflection.pets.*;
import java.util.function.*; import java.util.function.*;
class PerformingDogA extends Dog { class PerformingDogA extends Dog {

View File

@ -3,7 +3,7 @@
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// No (direct) latent typing in Java // No (direct) latent typing in Java
import typeinfo.pets.*; import reflection.pets.*;
class PerformingDog extends Dog implements Performs { class PerformingDog extends Dog implements Performs {
@Override @Override

View File

@ -10,7 +10,7 @@ public class GenericHolder<T> {
public T get() { return a; } public T get() { return a; }
public static void main(String[] args) { public static void main(String[] args) {
GenericHolder<Automobile> h3 = GenericHolder<Automobile> h3 =
new GenericHolder<Automobile>(); new GenericHolder<>();
h3.set(new Automobile()); // type checked h3.set(new Automobile()); // type checked
Automobile a = h3.get(); // No cast needed Automobile a = h3.get(); // No cast needed
//- h3.set("Not an Automobile"); // Error //- h3.set("Not an Automobile"); // Error

View File

@ -6,7 +6,7 @@ project(':validating') {
project(':equalshashcode') { project(':equalshashcode') {
dependencies { dependencies {
compile project(':typeinfo') compile project(':reflection')
compile project(':collections') compile project(':collections')
} }
} }
@ -48,13 +48,13 @@ project(':hiding') {
project(':generics') { project(':generics') {
dependencies { dependencies {
compile project(':typeinfo') compile project(':reflection')
} }
} }
project(':collections') { project(':collections') {
dependencies { dependencies {
compile project(':typeinfo') compile project(':reflection')
} }
} }

View File

@ -26,7 +26,7 @@ public class Flower {
} }
Flower() { Flower() {
this("hi", 47); this("hi", 47);
System.out.println("no-arg constructor"); System.out.println("Zero-argument constructor");
} }
void printPetalCount() { void printPetalCount() {
//- this(11); // Not inside non-constructor! //- this(11); // Not inside non-constructor!
@ -41,6 +41,6 @@ public class Flower {
/* Output: /* Output:
Constructor w/ int arg only, petalCount= 47 Constructor w/ int arg only, petalCount= 47
String & int args String & int args
no-arg constructor Zero-argument constructor
petalCount = 47 s = hi petalCount = 47 s = hi
*/ */

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Overloading based on the order of the arguments // Overloading based on parameter order
public class OverloadingOrder { public class OverloadingOrder {
static void f(String s, int i) { static void f(String s, int i) {

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Constructors can have arguments // Constructors can have parameters
class Rock2 { class Rock2 {
Rock2(int i) { Rock2(int i) {

View File

@ -2,6 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
/** You can <em>even</em> insert a list: /** You can <em>even</em> insert a list:
* <ol> * <ol>
* <li> Item one * <li> Item one
@ -9,4 +10,5 @@
* <li> Item three * <li> Item three
* </ol> * </ol>
*/ */
public class Documentation3 {} public class Documentation3 {}

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Supplier from a class with a no-arg constructor // Supplier from a class with a zero-argument constructor
package onjava; package onjava;
import java.util.function.*; import java.util.function.*;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;

View File

@ -130,7 +130,7 @@ public class Countries {
{"MOLDOVA","Chisinau"}, {"MOLDOVA","Chisinau"},
{"RUSSIA","Moscow"}, {"RUSSIA","Moscow"},
{"TAJIKISTAN","Dushanbe"}, {"TAJIKISTAN","Dushanbe"},
{"TURKMENISTAN","Ashkabad"}, {"TURKMENISTAN","Ashkhabad"},
{"UKRAINE","Kyiv"}, {"UKRAINE","Kyiv"},
{"UZBEKISTAN","Tashkent"}, {"UZBEKISTAN","Tashkent"},
// Europe // Europe

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Helper interface to allow lambda expressions // Helper interface to allow lambda expressions.
package onjava; package onjava;
import java.awt.event.*; import java.awt.event.*;

View File

@ -63,11 +63,11 @@ public class AtUnit implements ProcessFiles.Strategy {
.getDeclaredConstructor() .getDeclaredConstructor()
.getModifiers())) { .getModifiers())) {
System.out.println("Error: " + testClass + System.out.println("Error: " + testClass +
" no-arg constructor must be public"); " zero-argument constructor must be public");
System.exit(1); System.exit(1);
} }
} catch(NoSuchMethodException e) { } catch(NoSuchMethodException e) {
// Synthesized no-arg constructor; OK // Synthesized zero-argument constructor; OK
} }
System.out.println(testClass.getName()); System.out.println(testClass.getName());
} }
@ -159,7 +159,7 @@ public class AtUnit implements ProcessFiles.Strategy {
throw new RuntimeException("Couldn't run " + throw new RuntimeException("Couldn't run " +
"@TestObject (creator) method."); "@TestObject (creator) method.");
} }
} else { // Use the no-arg constructor: } else { // Use the zero-argument constructor:
try { try {
return testClass return testClass
.getConstructor().newInstance(); .getConstructor().newInstance();

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Demonstration of Observer pattern using // Demonstration of the Observer pattern using
// Java's built-in observer classes. // Java's built-in observer classes.
// {ExcludeFromGradle} // Won't work under WSL2 // {ExcludeFromGradle} // Won't work under WSL2
import javax.swing.*; import javax.swing.*;
@ -12,46 +12,34 @@ import java.util.*;
import onjava.*; import onjava.*;
import onjava.MouseClick; import onjava.MouseClick;
// You must inherit a new type of Observable:
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
class BoxObservable extends Observable { class Boxes extends JFrame {
@Override Observable notifier = new Observable() {
public void notifyObservers(Object b) { @Override
// Otherwise it won't propagate changes: public void notifyObservers(Object b) {
setChanged(); setChanged();
super.notifyObservers(b); super.notifyObservers(b);
} }
} };
public Boxes(int grid) {
@SuppressWarnings("deprecation")
public class BoxObserver extends JFrame {
Observable notifier = new BoxObservable();
public BoxObserver(int grid) {
setTitle("Demonstrates Observer pattern"); setTitle("Demonstrates Observer pattern");
Container cp = getContentPane(); Container cp = getContentPane();
cp.setLayout(new GridLayout(grid, grid)); cp.setLayout(new GridLayout(grid, grid));
for(int x = 0; x < grid; x++) for(int x = 0; x < grid; x++)
for(int y = 0; y < grid; y++) for(int y = 0; y < grid; y++)
cp.add(new OCBox(x, y, notifier)); cp.add(new Box(x, y, notifier));
} setSize(500, 400);
public static void main(String[] args) { setVisible(true);
// For automated test runs: setDefaultCloseOperation(DISPOSE_ON_CLOSE);
// new TimedAbort(4);
int grid = 8;
if(args.length > 0)
grid = Integer.parseInt(args[0]);
JFrame f = new BoxObserver(grid);
f.setSize(500, 400);
f.setVisible(true);
f.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
} }
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
class OCBox extends JPanel implements Observer { class Box extends JPanel implements Observer {
Observable notifier; int x, y; // Location in grid
int x, y; // Locations in grid Color color = COLORS[
Color cColor = newColor(); (int)(Math.random() * COLORS.length)
];
static final Color[] COLORS = { static final Color[] COLORS = {
Color.black, Color.blue, Color.cyan, Color.black, Color.blue, Color.cyan,
Color.darkGray, Color.gray, Color.green, Color.darkGray, Color.gray, Color.green,
@ -59,35 +47,38 @@ class OCBox extends JPanel implements Observer {
Color.orange, Color.pink, Color.red, Color.orange, Color.pink, Color.red,
Color.white, Color.yellow Color.white, Color.yellow
}; };
static Color newColor() { Box(int x, int y, Observable notifier) {
return COLORS[
(int)(Math.random() * COLORS.length)
];
}
OCBox(int x, int y, Observable notifier) {
this.x = x; this.x = x;
this.y = y; this.y = y;
notifier.addObserver(this); notifier.addObserver(this);
this.notifier = notifier;
addMouseListener((MouseClick) addMouseListener((MouseClick)
e -> notifier.notifyObservers(OCBox.this)); e -> notifier.notifyObservers(Box.this));
} }
@Override public void paintComponent(Graphics g) { @Override public void paintComponent(Graphics g) {
super.paintComponent(g); super.paintComponent(g);
g.setColor(cColor); g.setColor(color);
Dimension s = getSize(); Dimension s = getSize();
g.fillRect(0, 0, s.width, s.height); g.fillRect(0, 0, s.width, s.height);
} }
@Override @Override
public void update(Observable o, Object arg) { public void update(Observable o, Object arg) {
OCBox clicked = (OCBox)arg; Box clicked = (Box)arg;
if(nextTo(clicked)) { if(nextTo(clicked)) {
cColor = clicked.cColor; color = clicked.color;
repaint(); repaint();
} }
} }
private boolean nextTo(OCBox b) { private boolean nextTo(Box b) {
return Math.abs(x - b.x) <= 1 && return Math.abs(x - b.x) <= 1 &&
Math.abs(y - b.y) <= 1; Math.abs(y - b.y) <= 1;
} }
} }
public class BoxObserver {
public static void main(String[] args) {
int grid = 8;
if(args.length > 0)
grid = Integer.parseInt(args[0]);
new Boxes(grid);
}
}

View File

@ -0,0 +1,42 @@
// patterns/CleanTheFloor.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// State with different compositional interface.
class FloorCleaner {
private Attachment attachment = new Vacuum();
public void change(Attachment newAttachment) {
attachment = newAttachment;
}
public void clean() { attachment.action(); }
}
interface Attachment {
void action();
}
class Vacuum implements Attachment {
@Override public void action() {
System.out.println("Vacuuming");
}
}
class Mop implements Attachment {
@Override public void action() {
System.out.println("Mopping");
}
}
public class CleanTheFloor {
public static void main(String[] args) {
FloorCleaner floorCleaner = new FloorCleaner();
floorCleaner.clean();
floorCleaner.change(new Mop());
floorCleaner.clean();
}
}
/* Output:
Vacuuming
Mopping
*/

View File

@ -4,16 +4,23 @@
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
import java.util.*; import java.util.*;
class Command {
public final String msg;
public Command(String msg) {
this.msg = msg;
}
}
public class CommandPattern { public class CommandPattern {
public static void show(Command cmd) {
System.out.println(cmd.msg);
}
public static void main(String[] args) { public static void main(String[] args) {
List<Runnable> macro = Arrays.asList( show(new Command("First Command"));
() -> System.out.print("Hello "), show(new Command("Second Command"));
() -> System.out.print("World! "),
() -> System.out.print("I'm the command pattern!")
);
macro.forEach(Runnable::run);
} }
} }
/* Output: /* Output:
Hello World! I'm the command pattern! First Command
Second Command
*/ */

25
patterns/Macro.java Normal file
View File

@ -0,0 +1,25 @@
// patterns/Macro.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.*;
public class Macro {
public static void main(String[] args) {
List<Runnable> macro = new ArrayList<>(
Arrays.asList(
() -> System.out.print("Hello "),
() -> System.out.println("World! ")
));
macro.forEach(Runnable::run);
macro.add(
() -> System.out.print("I'm the command pattern!")
);
macro.forEach(Runnable::run);
}
}
/* Output:
Hello World!
Hello World!
I'm the command pattern!
*/

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Demonstration of multiple dispatching // Demonstration of multiple dispatching.
import java.util.*; import java.util.*;
import java.util.function.*; import java.util.function.*;
import java.util.stream.*; import java.util.stream.*;

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Simple demonstration of the Proxy pattern // Basic demonstration of the Proxy pattern.
interface ProxyBase { interface ProxyBase {
void f(); void f();
@ -11,10 +11,8 @@ interface ProxyBase {
} }
class Proxy implements ProxyBase { class Proxy implements ProxyBase {
private ProxyBase implementation; private ProxyBase implementation =
Proxy() { new Implementation();
implementation = new Implementation();
}
// Pass method calls to the implementation: // Pass method calls to the implementation:
@Override @Override
public void f() { implementation.f(); } public void f() { implementation.f(); }

9
patterns/Resource.java Normal file
View File

@ -0,0 +1,9 @@
// patterns/Resource.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
public interface Resource<T> {
T get();
void set(T x);
}

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// A simple static factory method // A basic static factory method.
import java.util.*; import java.util.*;
import java.util.stream.*; import java.util.stream.*;
import patterns.shapes.*; import patterns.shapes.*;

View File

@ -8,9 +8,9 @@ import java.util.stream.*;
import patterns.shapes.*; import patterns.shapes.*;
public class ShapeFactory2 implements FactoryMethod { public class ShapeFactory2 implements FactoryMethod {
Map<String, Constructor> factories = private Map<String, Constructor> factories =
new HashMap<>(); new HashMap<>();
static Constructor load(String id) { private static Constructor load(String id) {
System.out.println("loading " + id); System.out.println("loading " + id);
try { try {
return Class.forName("patterns.shapes." + id) return Class.forName("patterns.shapes." + id)

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Polymorphic factory methods // Polymorphic factory methods.
import java.util.*; import java.util.*;
import java.util.function.*; import java.util.function.*;
import java.util.stream.*; import java.util.stream.*;
@ -19,14 +19,15 @@ class RandomShapes implements Supplier<Shape> {
this.factories = factories; this.factories = factories;
} }
@Override public Shape get() { @Override public Shape get() {
return factories[ return
rand.nextInt(factories.length)].create(); factories[rand.nextInt(factories.length)]
.create();
} }
} }
public class ShapeFactory3 { public class ShapeFactory3 {
public static void main(String[] args) { public static void main(String[] args) {
RandomShapes rs = new RandomShapes( RandomShapes rs = new RandomShapes( // [1]
Circle::new, Square::new, Triangle::new Circle::new, Square::new, Triangle::new
); );
Stream.generate(rs) Stream.generate(rs)

18
patterns/Single.java Normal file
View File

@ -0,0 +1,18 @@
// patterns/Single.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
@SuppressWarnings("unchecked")
public final class Single<T> {
private static Object single; // [1]
public Single(T val) {
if(single != null)
throw new RuntimeException(
"Attempt to reassign Single<" +
val.getClass().getSimpleName() + ">"
);
single = val;
}
public T get() { return (T)single; }
}

View File

@ -3,58 +3,45 @@
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
interface Resource { final class IntegerSingleton
int getValue(); implements Resource<Integer> {
void setValue(int x); private static IntegerSingleton value =
} new IntegerSingleton();
private Integer i = Integer.valueOf(0);
// This isn't inherited from a Cloneable private IntegerSingleton() {
// base class and cloneability isn't added so System.out.println("IntegerSingleton()");
// making it final prevents cloneability from
// being added through inheritance. This also
// implements thread-safe lazy initialization:
final class Singleton {
private static final class
ResourceImpl implements Resource {
private int i;
private ResourceImpl(int i) {
this.i = i;
}
@Override
public synchronized int getValue() {
return i;
}
@Override
public synchronized void setValue(int x) {
i = x;
}
} }
private static class ResourceHolder { public static IntegerSingleton instance() {
private static Resource resource = return value;
new ResourceImpl(47);
}
public static Resource getResource() {
return ResourceHolder.resource;
} }
@Override public synchronized
Integer get() { return i; }
@Override public synchronized
void set(Integer x) { i = x; }
} }
public class SingletonPattern { public class SingletonPattern {
public static <T> void show(Resource<T> r) {
T val = r.get();
System.out.println(val);
}
public static <T> void put(Resource<T> r, T val) {
r.set(val);
}
public static void main(String[] args) { public static void main(String[] args) {
Resource r = Singleton.getResource(); System.out.println("Inside main()");
System.out.println(r.getValue()); Resource<Integer> ir =
Resource s2 = Singleton.getResource(); IntegerSingleton.instance();
s2.setValue(9); Resource<Integer> ir2 =
System.out.println(r.getValue()); IntegerSingleton.instance();
try { show(ir);
// Can't do this: compile-time error. put(ir2, Integer.valueOf(9));
// Singleton s3 = (Singleton)s2.clone(); show(ir);
} catch(Exception e) {
throw new RuntimeException(e);
}
} }
} }
/* Output: /* Output:
47 Inside main()
IntegerSingleton()
0
9 9
*/ */

View File

@ -0,0 +1,16 @@
// patterns/SingletonPattern2.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
public class SingletonPattern2 {
public static void main(String[] args) {
Single<Double> pi =
new Single<>(Double.valueOf(3.14159));
Double x = pi.get();
System.out.println(x);
}
}
/* Output:
3.14159
*/

View File

@ -0,0 +1,33 @@
// patterns/SingletonPattern3.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
class MyString {
private String s;
public MyString(String s) {
this.s = s;
}
public synchronized
void change(String s) {
this.s = s;
}
@Override public synchronized
String toString() {
return s;
}
}
public class SingletonPattern3 {
public static void main(String[] args) {
Single<MyString> x =
new Single<>(new MyString("Hello"));
System.out.println(x.get());
x.get().change("World!");
System.out.println(x.get());
}
}
/* Output:
Hello
World!
*/

View File

@ -2,34 +2,24 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Simple demonstration of the State pattern // Basic demonstration of the State pattern.
interface StateBase { class State {
void f(); private State implementation;
void g(); protected State() {}
void h(); public State(State imp) {
void changeImp(StateBase newImp);
}
class State implements StateBase {
private StateBase implementation;
State(StateBase imp) {
implementation = imp; implementation = imp;
} }
@Override public void change(State newImp) {
public void changeImp(StateBase newImp) {
implementation = newImp; implementation = newImp;
} }
// Pass method calls to the implementation: // Forward method calls to the implementation:
@Override
public void f() { implementation.f(); } public void f() { implementation.f(); }
@Override
public void g() { implementation.g(); } public void g() { implementation.g(); }
@Override
public void h() { implementation.h(); } public void h() { implementation.h(); }
} }
class Implementation1 implements StateBase { class Implementation1 extends State {
@Override public void f() { @Override public void f() {
System.out.println("Implementation1.f()"); System.out.println("Implementation1.f()");
} }
@ -39,11 +29,9 @@ class Implementation1 implements StateBase {
@Override public void h() { @Override public void h() {
System.out.println("Implementation1.h()"); System.out.println("Implementation1.h()");
} }
@Override
public void changeImp(StateBase newImp) {}
} }
class Implementation2 implements StateBase { class Implementation2 extends State {
@Override public void f() { @Override public void f() {
System.out.println("Implementation2.f()"); System.out.println("Implementation2.f()");
} }
@ -53,28 +41,27 @@ class Implementation2 implements StateBase {
@Override public void h() { @Override public void h() {
System.out.println("Implementation2.h()"); System.out.println("Implementation2.h()");
} }
@Override
public void changeImp(StateBase newImp) {}
} }
public class StateDemo { public class StateDemo {
static void test(StateBase b) { static void test(State s) {
b.f(); s.f();
b.g(); s.g();
b.h(); s.h();
} }
public static void main(String[] args) { public static void main(String[] args) {
StateBase b = State s = new State(new Implementation1());
new State(new Implementation1()); test(s);
test(b); System.out.println("Changing implementation");
b.changeImp(new Implementation2()); s.change(new Implementation2());
test(b); test(s);
} }
} }
/* Output: /* Output:
Implementation1.f() Implementation1.f()
Implementation1.g() Implementation1.g()
Implementation1.h() Implementation1.h()
Changing implementation
Implementation2.f() Implementation2.f()
Implementation2.g() Implementation2.g()
Implementation2.h() Implementation2.h()

View File

@ -2,29 +2,29 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Simple demonstration of Template Method // Basic Template Method pattern.
import java.util.stream.*; import java.util.stream.*;
abstract class ApplicationFramework { abstract class ApplicationFramework {
ApplicationFramework() { ApplicationFramework() {
templateMethod(); templateMethod();
} }
abstract void customize1(); abstract void customize1(int n);
abstract void customize2(); abstract void customize2(int n);
// "private" means automatically "final": // "private" means automatically "final":
private void templateMethod() { private void templateMethod() {
IntStream.range(0, 5).forEach( IntStream.range(0, 5).forEach(
n -> { customize1(); customize2(); }); n -> { customize1(n); customize2(n); });
} }
} }
// Create a new "application": // Create a new application:
class MyApp extends ApplicationFramework { class MyApp extends ApplicationFramework {
@Override void customize1() { @Override void customize1(int n) {
System.out.print("Hello "); System.out.print("customize1 " + n);
} }
@Override void customize2() { @Override void customize2(int n) {
System.out.println("World!"); System.out.println(" customize2 " + n);
} }
} }
@ -34,9 +34,9 @@ public class TemplateMethod {
} }
} }
/* Output: /* Output:
Hello World! customize1 0 customize2 0
Hello World! customize1 1 customize2 1
Hello World! customize1 2 customize2 2
Hello World! customize1 3 customize2 3
Hello World! customize1 4 customize2 4
*/ */

20
patterns/TestSingle.java Normal file
View File

@ -0,0 +1,20 @@
// patterns/TestSingle.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
public class TestSingle {
public static void main(String[] args) {
Single<String> ss = new Single<>("hello");
System.out.println(ss.get());
try {
Single<String> ss2 = new Single<>("world");
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
/* Output:
hello
Attempt to reassign Single<String>
*/

21
patterns/TypeMap.java Normal file
View File

@ -0,0 +1,21 @@
// patterns/TypeMap.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Generic TypeMap works for any types.
package patterns;
import java.util.*;
import java.util.stream.*;
public class TypeMap<T> {
public final Map<Class, List<T>> map =
new HashMap<>();
public void add(T o) {
Class type = o.getClass();
map.computeIfAbsent(type,
k -> new ArrayList<T>()).add(o);
}
public Stream<List<T>> values() {
return map.values().stream();
}
}

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// An example of the Abstract Factory pattern // An example of the Abstract Factory pattern.
// {java patterns.abstractfactory.GameEnvironment} // {java patterns.abstractfactory.GameEnvironment}
package patterns.abstractfactory; package patterns.abstractfactory;
import java.util.function.*; import java.util.function.*;
@ -23,10 +23,10 @@ class Kitty implements Player {
} }
} }
class KungFuGuy implements Player { class Fighter implements Player {
@Override @Override
public void interactWith(Obstacle ob) { public void interactWith(Obstacle ob) {
System.out.print("KungFuGuy now battles a "); System.out.print("Fighter now battles a ");
ob.action(); ob.action();
} }
} }
@ -37,9 +37,9 @@ class Puzzle implements Obstacle {
} }
} }
class NastyWeapon implements Obstacle { class Weapon implements Obstacle {
@Override public void action() { @Override public void action() {
System.out.println("NastyWeapon"); System.out.println("Weapon");
} }
} }
@ -58,11 +58,11 @@ extends GameElementFactory {
} }
} }
class KillAndDismember class Melee
extends GameElementFactory { extends GameElementFactory {
KillAndDismember() { Melee() {
player = KungFuGuy::new; player = Fighter::new;
obstacle = NastyWeapon::new; obstacle = Weapon::new;
} }
} }
@ -80,15 +80,15 @@ public class GameEnvironment {
public static void main(String[] args) { public static void main(String[] args) {
GameElementFactory GameElementFactory
kp = new KittiesAndPuzzles(), kp = new KittiesAndPuzzles(),
kd = new KillAndDismember(); ml = new Melee();
GameEnvironment GameEnvironment
g1 = new GameEnvironment(kp), g1 = new GameEnvironment(kp),
g2 = new GameEnvironment(kd); g2 = new GameEnvironment(ml);
g1.play(); g1.play();
g2.play(); g2.play();
} }
} }
/* Output: /* Output:
Kitty has encountered a Puzzle Kitty has encountered a Puzzle
KungFuGuy now battles a NastyWeapon Fighter now battles a Weapon
*/ */

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Variations on the Adapter pattern // Variations on the Adapter pattern.
// {java patterns.adapt.Adapter} // {java patterns.adapt.Adapter}
package patterns.adapt; package patterns.adapt;

View File

@ -2,55 +2,32 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Using the Functional interface
// {java patterns.chain.ChainOfResponsibility} // {java patterns.chain.ChainOfResponsibility}
package patterns.chain; package patterns.chain;
import java.util.*; import java.util.*;
import java.util.function.*; import java.util.function.*;
class Result {
boolean success;
List<Double> line;
Result(List<Double> data) {
success = true;
line = data;
}
Result() {
success = false;
line = Collections.<Double>emptyList();
}
}
class Fail extends Result {}
interface Algorithm { interface Algorithm {
Result algorithm(List<Double> line); Result algorithm(List<Double> line);
} }
class FindMinima { class FindMinima {
public static Result leastSquares(List<Double> line) { public static Result test(
System.out.println("LeastSquares.algorithm"); boolean success, String id, double d1, double d2) {
boolean weSucceed = false; System.out.println(id);
if(weSucceed) // Actual test/calculation here if(success) // Actual test/calculation here
return new Result(Arrays.asList(1.1, 2.2)); return new Result(Arrays.asList(d1, d2));
else // Try the next one in the chain: else // Try the next one in the chain:
return new Fail(); return Result.fail;
}
public static Result leastSquares(List<Double> line) {
return test(false, "LeastSquares", 1.1, 2.2);
} }
public static Result perturbation(List<Double> line) { public static Result perturbation(List<Double> line) {
System.out.println("Perturbation.algorithm"); return test(false, "Perturbation", 3.3, 4.4);
boolean weSucceed = false;
if(weSucceed) // Actual test/calculation here
return new Result(Arrays.asList(3.3, 4.4));
else
return new Fail();
} }
public static Result bisection(List<Double> line) { public static Result bisection(List<Double> line) {
System.out.println("Bisection.algorithm"); return test(true, "Bisection", 5.5, 6.6);
boolean weSucceed = true;
if(weSucceed) // Actual test/calculation here
return new Result(Arrays.asList(5.5, 6.6));
else
return new Fail();
} }
static List<Function<List<Double>, Result>> static List<Function<List<Double>, Result>>
algorithms = Arrays.asList( algorithms = Arrays.asList(
@ -65,7 +42,7 @@ class FindMinima {
if(result.success) if(result.success)
return result; return result;
} }
return new Fail(); return Result.fail;
} }
} }
@ -83,8 +60,8 @@ public class ChainOfResponsibility {
} }
} }
/* Output: /* Output:
LeastSquares.algorithm LeastSquares
Perturbation.algorithm Perturbation
Bisection.algorithm Bisection
[5.5, 6.6] [5.5, 6.6]
*/ */

View File

@ -0,0 +1,21 @@
// patterns/chain/Result.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Carries the result or indicates failure.
package patterns.chain;
import java.util.*;
public class Result {
public final boolean success;
public final List<Double> line;
public Result(List<Double> data) {
success = true;
line = data;
}
private Result() {
success = false;
line = Collections.<Double>emptyList();
}
public static final Result fail = new Result();
}

View File

@ -2,13 +2,13 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Aluminum for double dispatching // Aluminum with double dispatching.
package patterns.doubledispatch; package patterns.doubledispatch;
import patterns.trash.*; import patterns.trash.*;
import java.util.*; import java.util.*;
public class Aluminum extends patterns.trash.Aluminum public class Aluminum extends patterns.trash.Aluminum
implements TypedBinMember { implements TypedBinMember {
public Aluminum(double wt) { super(wt); } public Aluminum(double wt) { super(wt); }
@Override @Override
public boolean addToBin(List<TypedBin> tbins) { public boolean addToBin(List<TypedBin> tbins) {

View File

@ -2,13 +2,13 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Cardboard for double dispatching // Cardboard with double dispatching.
package patterns.doubledispatch; package patterns.doubledispatch;
import patterns.trash.*; import patterns.trash.*;
import java.util.*; import java.util.*;
public class Cardboard extends patterns.trash.Cardboard public class Cardboard extends patterns.trash.Cardboard
implements TypedBinMember { implements TypedBinMember {
public Cardboard(double wt) { super(wt); } public Cardboard(double wt) { super(wt); }
@Override @Override
public boolean addToBin(List<TypedBin> tbins) { public boolean addToBin(List<TypedBin> tbins) {

View File

@ -3,90 +3,104 @@
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Using multiple dispatching to handle more // Using multiple dispatching to handle more
// than one unknown type during a method call // than one unknown type during a method call.
// {java patterns.doubledispatch.DoubleDispatch} // {java patterns.doubledispatch.DoubleDispatch}
package patterns.doubledispatch; package patterns.doubledispatch;
import patterns.trash.*; import patterns.trash.*;
import java.util.*; import java.util.*;
class AluminumBin extends TypedBin { class AluminumBin extends TypedBin {
public AluminumBin() { super("Aluminum"); }
@Override public boolean add(Aluminum a) { @Override public boolean add(Aluminum a) {
return addIt(a); return addIt(a);
} }
} }
class PaperBin extends TypedBin { class PaperBin extends TypedBin {
public PaperBin() { super("Paper"); }
@Override public boolean add(Paper a) { @Override public boolean add(Paper a) {
return addIt(a); return addIt(a);
} }
} }
class GlassBin extends TypedBin { class GlassBin extends TypedBin {
public GlassBin() { super("Glass"); }
@Override public boolean add(Glass a) { @Override public boolean add(Glass a) {
return addIt(a); return addIt(a);
} }
} }
class CardboardBin extends TypedBin { class CardboardBin extends TypedBin {
public CardboardBin() { super("Cardboard"); }
@Override public boolean add(Cardboard a) { @Override public boolean add(Cardboard a) {
return addIt(a); return addIt(a);
} }
} }
class TrashBinSet { class TrashBinSet {
private List<TypedBin> binSet = Arrays.asList( public final List<TypedBin> binSet =
new AluminumBin(), Arrays.asList(
new PaperBin(), new AluminumBin(), new PaperBin(),
new GlassBin(), new GlassBin(), new CardboardBin()
new CardboardBin() );
);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void sortIntoBins(List bin) { public void sortIntoBins(List bin) {
bin.forEach( aBin -> { bin.forEach( aBin -> {
TypedBinMember t = (TypedBinMember)aBin; TypedBinMember t = (TypedBinMember)aBin;
if(!t.addToBin(binSet)) if(!t.addToBin(binSet))
System.err.println("Couldn't add " + t); throw new RuntimeException(
"sortIntoBins() couldn't add " + t);
}); });
} }
public List<TypedBin> binSet() { return binSet; }
} }
public class DoubleDispatch { public class DoubleDispatch {
public static void main(String[] args) { public static void main(String[] args) {
List<Trash> bin = new ArrayList<>(); List<Trash> bin = new ArrayList<>();
TrashBinSet bins = new TrashBinSet();
// ParseTrash still works, without changes:
ParseTrash.fillBin("doubledispatch", bin); ParseTrash.fillBin("doubledispatch", bin);
TrashBinSet bins = new TrashBinSet();
// Sort from the master bin into the // Sort from the master bin into the
// individually-typed bins: // individually-typed bins:
bins.sortIntoBins(bin); bins.sortIntoBins(bin);
// Perform sumValue for each bin... // Sum value of each bin...
bins.binSet() bins.binSet.forEach(tb ->
.forEach(tb -> Trash.sumValue(tb.v)); TrashValue.sum(tb.bin(), tb.type));
// ... and for the master bin // ... and for the master bin:
Trash.sumValue(bin); TrashValue.sum(bin, "Trash");
} }
} }
/* Output: (First and Last 10 Lines) /* Output:
Loading patterns.doubledispatch.Glass Loading patterns.doubledispatch.Cardboard
Loading patterns.doubledispatch.Paper Loading patterns.doubledispatch.Paper
Loading patterns.doubledispatch.Aluminum Loading patterns.doubledispatch.Aluminum
Loading patterns.doubledispatch.Cardboard Loading patterns.doubledispatch.Glass
weight of patterns.doubledispatch.Aluminum = 89.0 Aluminum weight: 1.80 * price: 1.67 = 3.01
weight of patterns.doubledispatch.Aluminum = 76.0 Aluminum weight: 3.40 * price: 1.67 = 5.68
weight of patterns.doubledispatch.Aluminum = 25.0 Aluminum weight: 2.70 * price: 1.67 = 4.51
weight of patterns.doubledispatch.Aluminum = 34.0 Total Aluminum value = 13.19
weight of patterns.doubledispatch.Aluminum = 27.0 Paper weight: 8.00 * price: 0.10 = 0.80
weight of patterns.doubledispatch.Aluminum = 18.0 Paper weight: 6.60 * price: 0.10 = 0.66
...________...________...________...________... Paper weight: 9.10 * price: 0.10 = 0.91
weight of patterns.doubledispatch.Aluminum = 93.0 Total Paper value = 2.37
weight of patterns.doubledispatch.Glass = 93.0 Glass weight: 5.40 * price: 0.23 = 1.24
weight of patterns.doubledispatch.Paper = 80.0 Glass weight: 4.30 * price: 0.23 = 0.99
weight of patterns.doubledispatch.Glass = 36.0 Glass weight: 3.60 * price: 0.23 = 0.83
weight of patterns.doubledispatch.Glass = 12.0 Total Glass value = 3.06
weight of patterns.doubledispatch.Glass = 60.0 Cardboard weight: 4.40 * price: 0.11 = 0.48
weight of patterns.doubledispatch.Paper = 66.0 Cardboard weight: 2.20 * price: 0.11 = 0.24
weight of patterns.doubledispatch.Aluminum = 36.0 Cardboard weight: 1.20 * price: 0.11 = 0.13
weight of patterns.doubledispatch.Cardboard = 22.0 Total Cardboard value = 0.86
Total value = 1086.0599818825722 Cardboard weight: 4.40 * price: 0.11 = 0.48
Paper weight: 8.00 * price: 0.10 = 0.80
Aluminum weight: 1.80 * price: 1.67 = 3.01
Glass weight: 5.40 * price: 0.23 = 1.24
Aluminum weight: 3.40 * price: 1.67 = 5.68
Cardboard weight: 2.20 * price: 0.11 = 0.24
Glass weight: 4.30 * price: 0.23 = 0.99
Cardboard weight: 1.20 * price: 0.11 = 0.13
Paper weight: 6.60 * price: 0.10 = 0.66
Aluminum weight: 2.70 * price: 1.67 = 4.51
Paper weight: 9.10 * price: 0.10 = 0.91
Glass weight: 3.60 * price: 0.23 = 0.83
Total Trash value = 19.48
*/ */

View File

@ -2,13 +2,13 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Glass for double dispatching // Glass with double dispatching.
package patterns.doubledispatch; package patterns.doubledispatch;
import patterns.trash.*; import patterns.trash.*;
import java.util.*; import java.util.*;
public class Glass extends patterns.trash.Glass public class Glass extends patterns.trash.Glass
implements TypedBinMember { implements TypedBinMember {
public Glass(double wt) { super(wt); } public Glass(double wt) { super(wt); }
@Override @Override
public boolean addToBin(List<TypedBin> tbins) { public boolean addToBin(List<TypedBin> tbins) {

View File

@ -2,13 +2,13 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Paper for double dispatching // Paper with double dispatching.
package patterns.doubledispatch; package patterns.doubledispatch;
import patterns.trash.*; import patterns.trash.*;
import java.util.*; import java.util.*;
public class Paper extends patterns.trash.Paper public class Paper extends patterns.trash.Paper
implements TypedBinMember { implements TypedBinMember {
public Paper(double wt) { super(wt); } public Paper(double wt) { super(wt); }
@Override @Override
public boolean addToBin(List<TypedBin> tbins) { public boolean addToBin(List<TypedBin> tbins) {

View File

@ -2,15 +2,24 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// A List that can grab the right type // A List that can grab the right type.
package patterns.doubledispatch; package patterns.doubledispatch;
import patterns.trash.*; import patterns.trash.*;
import java.util.*; import java.util.*;
public class TypedBin { public class TypedBin {
List<Trash> v = new ArrayList<>(); private List<Trash> typedBin =
new ArrayList<>();
public final String type;
public TypedBin(String type) {
this.type = type;
}
public List<Trash> bin() {
// Returns a copy of typedBin:
return new ArrayList<Trash>(typedBin);
}
protected boolean addIt(Trash t) { protected boolean addIt(Trash t) {
v.add(t); typedBin.add(t);
return true; return true;
} }
public boolean add(Aluminum a) { public boolean add(Aluminum a) {

View File

@ -2,13 +2,12 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// An interface for adding the double dispatching // Adapts the double-dispatching
// method to the trash hierarchy without // method into the trash hierarchy without
// modifying the original hierarchy // modifying the original hierarchy.
package patterns.doubledispatch; package patterns.doubledispatch;
import java.util.*; import java.util.*;
public interface TypedBinMember { public interface TypedBinMember {
// The new method:
boolean addToBin(List<TypedBin> bins); boolean addToBin(List<TypedBin> bins);
} }

View File

@ -1,74 +0,0 @@
// patterns/dynatrash/DynaTrash.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Using a Map of Lists and RTTI to automatically
// sort trash into Lists. This solution, despite
// the use of RTTI, is extensible.
// {java patterns.dynatrash.DynaTrash}
package patterns.dynatrash;
import patterns.trash.*;
import java.util.*;
import java.util.stream.*;
// Generic TypeMap works in any situation:
class TypeMap<T> {
private Map<Class,List<T>> t = new HashMap<>();
public void add(T o) {
Class type = o.getClass();
if(t.containsKey(type))
t.get(type).add(o);
else {
List<T> v = new ArrayList<>();
v.add(o);
t.put(type,v);
}
}
public Stream<List<T>> values() {
return t.values().stream();
}
}
// Adapter class for callbacks
// from ParseTrash.fillBin():
class TypeMapAdapter implements Fillable {
TypeMap<Trash> map;
TypeMapAdapter(TypeMap<Trash> tm) {
map = tm;
}
@Override
public void addTrash(Trash t) { map.add(t); }
}
public class DynaTrash {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
TypeMap<Trash> bin = new TypeMap<>();
ParseTrash.fillBin(
"trash", new TypeMapAdapter(bin));
bin.values().forEach(Trash::sumValue);
}
}
/* Output: (First and Last 10 Lines)
Loading patterns.trash.Glass
Loading patterns.trash.Paper
Loading patterns.trash.Aluminum
Loading patterns.trash.Cardboard
weight of patterns.trash.Paper = 22.0
weight of patterns.trash.Paper = 11.0
weight of patterns.trash.Paper = 88.0
weight of patterns.trash.Paper = 91.0
weight of patterns.trash.Paper = 80.0
weight of patterns.trash.Paper = 66.0
...________...________...________...________...
weight of patterns.trash.Glass = 93.0
weight of patterns.trash.Glass = 36.0
weight of patterns.trash.Glass = 12.0
weight of patterns.trash.Glass = 60.0
Total value = 150.1900027245283
weight of patterns.trash.Cardboard = 96.0
weight of patterns.trash.Cardboard = 44.0
weight of patterns.trash.Cardboard = 12.0
weight of patterns.trash.Cardboard = 22.0
Total value = 40.02000072598457
*/

View File

@ -2,19 +2,35 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Demonstration of "Observer" pattern // Demonstration of the Observer pattern.
// {java patterns.observer.ObservedFlower} // {java patterns.observer.ObservedFlower}
package patterns.observer; package patterns.observer;
import java.util.*; import java.util.*;
import java.util.function.*;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
class Flower { class Flower {
private boolean isOpen; private boolean isOpen = false;
private boolean alreadyOpen; private boolean alreadyOpen = false;
private boolean alreadyClosed; private boolean alreadyClosed = false;
Flower() { isOpen = false; } Observable opening = new Observable() {
OpenNotifier opening = new OpenNotifier(); @Override public void notifyObservers() {
CloseNotifier closing = new CloseNotifier(); if(isOpen && !alreadyOpen) {
setChanged();
super.notifyObservers();
alreadyOpen = true;
}
}
};
Observable closing = new Observable() {
@Override public void notifyObservers() {
if(!isOpen && !alreadyClosed) {
setChanged();
super.notifyObservers();
alreadyClosed = true;
}
}
};
public void open() { // Opens its petals public void open() { // Opens its petals
isOpen = true; isOpen = true;
opening.notifyObservers(); opening.notifyObservers();
@ -25,55 +41,32 @@ class Flower {
closing.notifyObservers(); closing.notifyObservers();
alreadyOpen = false; alreadyOpen = false;
} }
class OpenNotifier extends Observable {
@Override public void notifyObservers() {
if(isOpen && !alreadyOpen) {
setChanged();
super.notifyObservers();
alreadyOpen = true;
}
}
}
class CloseNotifier extends Observable{
@Override public void notifyObservers() {
if(!isOpen && !alreadyClosed) {
setChanged();
super.notifyObservers();
alreadyClosed = true;
}
}
}
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
class Bee { class Bee {
private String name; private String id;
Bee(String nm) { name = nm; } Bee(String name) { id = name; }
// Observe openings: // Observe openings:
public Observer openObserver() { public final Observer whenOpened = (ob, a) ->
return (ob, a) -> System.out.println( System.out.println(
"Bee " + name + "'s breakfast time!"); "Bee " + id + "'s breakfast time!");
}
// Observe closings: // Observe closings:
public Observer closeObserver() { public final Observer whenClosed = (ob, a) ->
return (ob, a) -> System.out.println( System.out.println(
"Bee " + name + "'s bed time!"); "Bee " + id + "'s bed time!");
}
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
class Hummingbird { class Hummingbird {
private String name; private String id;
Hummingbird(String nm) { name = nm; } Hummingbird(String name) { id = name; }
public Observer openObserver() { public final Observer whenOpened = (ob, a) ->
return (ob, a) -> System.out.println( System.out.println("Hummingbird " +
"Hummingbird " + name + id + "'s breakfast time!");
"'s breakfast time!"); public final Observer whenClosed = (ob, a) ->
} System.out.println("Hummingbird " +
public Observer closeObserver() { id + "'s bed time!");
return (ob, a) -> System.out.println(
"Hummingbird " + name + "'s bed time!");
}
} }
public class ObservedFlower { public class ObservedFlower {
@ -85,39 +78,46 @@ public class ObservedFlower {
Hummingbird Hummingbird
ha = new Hummingbird("A"), ha = new Hummingbird("A"),
hb = new Hummingbird("B"); hb = new Hummingbird("B");
f.opening.addObserver(ha.openObserver()); f.opening.addObserver(ha.whenOpened);
f.opening.addObserver(hb.openObserver()); f.opening.addObserver(hb.whenOpened);
f.opening.addObserver(ba.openObserver()); f.opening.addObserver(ba.whenOpened);
f.opening.addObserver(bb.openObserver()); f.opening.addObserver(bb.whenOpened);
f.closing.addObserver(ha.closeObserver()); f.closing.addObserver(ha.whenClosed);
f.closing.addObserver(hb.closeObserver()); f.closing.addObserver(hb.whenClosed);
f.closing.addObserver(ba.closeObserver()); f.closing.addObserver(ba.whenClosed);
f.closing.addObserver(bb.closeObserver()); f.closing.addObserver(bb.whenClosed);
// Hummingbird B decides to sleep in: // Hummingbird B decides to sleep in.
f.opening.deleteObserver(hb.openObserver()); // Removing whenOpened stops open updates.
f.opening.deleteObserver(hb.whenOpened);
// A change that interests observers: // A change that interests observers:
f.open(); f.open();
f.open(); // It's already open, no change. f.open(); // No effect: it's already open.
// Bee A doesn't want to go to bed: System.out.println("---------------");
f.closing.deleteObserver(ba.closeObserver()); // Bee A doesn't want to go to bed.
// Removing whenClosed stops close updates.
f.closing.deleteObserver(ba.whenClosed);
f.close(); f.close();
f.close(); // It's already closed; no change System.out.println("+++++++++++++++");
f.close(); // No effect: it's already closed.
System.out.println("===============");
f.opening.deleteObservers(); f.opening.deleteObservers();
f.open(); f.open(); // No observers to update.
f.close(); System.out.println("###############");
f.close(); // Close observers are still there.
} }
} }
/* Output: /* Output:
Bee B's breakfast time! Bee B's breakfast time!
Bee A's breakfast time! Bee A's breakfast time!
Hummingbird B's breakfast time!
Hummingbird A's breakfast time! Hummingbird A's breakfast time!
---------------
Bee B's bed time! Bee B's bed time!
Bee A's bed time!
Hummingbird B's bed time! Hummingbird B's bed time!
Hummingbird A's bed time! Hummingbird A's bed time!
+++++++++++++++
===============
###############
Bee B's bed time! Bee B's bed time!
Bee A's bed time!
Hummingbird B's bed time! Hummingbird B's bed time!
Hummingbird A's bed time! Hummingbird A's bed time!
*/ */

View File

@ -2,72 +2,25 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Recycling with RTTI // Recycling with reflection.
// {java patterns.recyclea.RecycleA} // {java patterns.recyclea.RecycleA}
package patterns.recyclea; package patterns.recyclea;
import java.util.*; import java.util.*;
import java.util.function.*; import java.util.function.*;
import java.util.stream.*; import java.util.stream.*;
import patterns.trash.*;
abstract class Trash { class SimpleFactory {
double weight; static final
Trash(double wt) { weight = wt; } List<Function<Double, Trash>> constructors =
abstract double value();
// Sums the value of Trash in a bin:
private static double val;
static void sumValue(List<? extends Trash> bin) {
val = 0.0f;
bin.forEach( t -> {
// Polymorphism in action:
val += t.weight * t.value();
System.out.println(
"weight of " +
// Using RTTI to get type
// information about the class:
t.getClass().getSimpleName() +
" = " + t.weight);
});
System.out.println("Total value = " + val);
}
}
class Aluminum extends Trash {
static double val = 1.67f;
Aluminum(double wt) { super(wt); }
@Override double value() { return val; }
static void value(double newval) {
val = newval;
}
}
class Paper extends Trash {
static double val = 0.10f;
Paper(double wt) { super(wt); }
@Override double value() { return val; }
static void value(double newval) {
val = newval;
}
}
class Glass extends Trash {
static double val = 0.23f;
Glass(double wt) { super(wt); }
@Override double value() { return val; }
static void value(double newval) {
val = newval;
}
}
class TrashFactory {
static List<Function<Double, Trash>> ttypes =
Arrays.asList( Arrays.asList(
Aluminum::new, Paper::new, Glass::new); Aluminum::new, Paper::new, Glass::new);
static final int SZ = ttypes.size(); static final int SIZE = constructors.size();
private static SplittableRandom rand = private static SplittableRandom rand =
new SplittableRandom(47); new SplittableRandom(42);
public static Trash newTrash() { public static Trash random() {
return ttypes return constructors
.get(rand.nextInt(SZ)) .get(rand.nextInt(SIZE))
.apply(rand.nextDouble()); .apply(rand.nextDouble());
} }
} }
@ -75,50 +28,37 @@ class TrashFactory {
public class RecycleA { public class RecycleA {
public static void main(String[] args) { public static void main(String[] args) {
List<Trash> bin = List<Trash> bin =
Stream.generate(TrashFactory::newTrash) Stream.generate(SimpleFactory::random)
.limit(25) .limit(10)
.collect(Collectors.toList()); .collect(Collectors.toList());
List<Glass> glassBin = new ArrayList<>(); Bins bins = new Bins(bin);
List<Paper> paperBin = new ArrayList<>(); bins.show();
List<Aluminum> alBin = new ArrayList<>();
// Sort the Trash:
bin.forEach( t -> {
// RTTI to discover Trash type:
if(t instanceof Aluminum)
alBin.add((Aluminum)t);
if(t instanceof Paper)
paperBin.add((Paper)t);
if(t instanceof Glass)
glassBin.add((Glass)t);
});
Trash.sumValue(alBin);
Trash.sumValue(paperBin);
Trash.sumValue(glassBin);
Trash.sumValue(bin);
} }
} }
/* Output: (First and Last 11 Lines) /* Output:
weight of Aluminum = 0.2893030122276371 Aluminum weight: 0.34 * price: 1.67 = 0.57
weight of Aluminum = 0.1970234961398979 Aluminum weight: 0.62 * price: 1.67 = 1.03
weight of Aluminum = 0.36295525806274787 Aluminum weight: 0.49 * price: 1.67 = 0.82
weight of Aluminum = 0.4825532324565849 Aluminum weight: 0.50 * price: 1.67 = 0.83
weight of Aluminum = 0.8036398273294586 Total Aluminum value = 3.26
weight of Aluminum = 0.510430896154935 Paper weight: 0.69 * price: 0.10 = 0.07
weight of Aluminum = 0.6703377164093444 Total Paper value = 0.07
weight of Aluminum = 0.41477933066243455 Glass weight: 0.16 * price: 0.23 = 0.04
weight of Aluminum = 0.3603022312124007 Glass weight: 0.87 * price: 0.23 = 0.20
weight of Aluminum = 0.43690089841661006 Glass weight: 0.80 * price: 0.23 = 0.18
weight of Aluminum = 0.6708820087907101 Glass weight: 0.52 * price: 0.23 = 0.12
...________...________...________...________... Glass weight: 0.20 * price: 0.23 = 0.05
weight of Aluminum = 0.41477933066243455 Total Glass value = 0.59
weight of Aluminum = 0.3603022312124007 Total Cardboard value = 0.00
weight of Aluminum = 0.43690089841661006 Glass weight: 0.16 * price: 0.23 = 0.04
weight of Glass = 0.5999637765664924 Aluminum weight: 0.34 * price: 1.67 = 0.57
weight of Glass = 0.7748836191212746 Glass weight: 0.87 * price: 0.23 = 0.20
weight of Paper = 0.5735994548427199 Glass weight: 0.80 * price: 0.23 = 0.18
weight of Glass = 0.5362827750851034 Aluminum weight: 0.62 * price: 1.67 = 1.03
weight of Aluminum = 0.6708820087907101 Aluminum weight: 0.49 * price: 1.67 = 0.82
weight of Paper = 0.8370669795210507 Glass weight: 0.52 * price: 0.23 = 0.12
weight of Glass = 0.3397919679731668 Glass weight: 0.20 * price: 0.23 = 0.05
Total value = 9.90671597531968 Aluminum weight: 0.50 * price: 1.67 = 0.83
Paper weight: 0.69 * price: 0.10 = 0.07
Total Trash value = 3.91
*/ */

View File

@ -10,47 +10,43 @@ import java.util.*;
public class RecycleB { public class RecycleB {
public static void main(String[] args) { public static void main(String[] args) {
List<Trash> bin = new ArrayList<>(); List<Trash> bin = new ArrayList<>();
// Fill up the Trash bin:
ParseTrash.fillBin("trash", bin); ParseTrash.fillBin("trash", bin);
List<Glass> glassBin = new ArrayList<>(); Bins bins = new Bins(bin);
List<Paper> paperBin = new ArrayList<>(); bins.show();
List<Aluminum> alBin = new ArrayList<>();
// Sort the Trash:
bin.forEach( t -> {
// RTTI to discover Trash type:
if(t instanceof Aluminum)
alBin.add((Aluminum)t);
if(t instanceof Paper)
paperBin.add((Paper)t);
if(t instanceof Glass)
glassBin.add((Glass)t);
});
Trash.sumValue(alBin);
Trash.sumValue(paperBin);
Trash.sumValue(glassBin);
Trash.sumValue(bin);
} }
} }
/* Output: (First and Last 10 Lines) /* Output:
Loading patterns.trash.Glass Loading patterns.trash.Cardboard
Loading patterns.trash.Paper Loading patterns.trash.Paper
Loading patterns.trash.Aluminum Loading patterns.trash.Aluminum
Loading patterns.trash.Cardboard Loading patterns.trash.Glass
weight of patterns.trash.Aluminum = 89.0 Aluminum weight: 1.80 * price: 1.67 = 3.01
weight of patterns.trash.Aluminum = 76.0 Aluminum weight: 3.40 * price: 1.67 = 5.68
weight of patterns.trash.Aluminum = 25.0 Aluminum weight: 2.70 * price: 1.67 = 4.51
weight of patterns.trash.Aluminum = 34.0 Total Aluminum value = 13.19
weight of patterns.trash.Aluminum = 27.0 Paper weight: 8.00 * price: 0.10 = 0.80
weight of patterns.trash.Aluminum = 18.0 Paper weight: 6.60 * price: 0.10 = 0.66
...________...________...________...________... Paper weight: 9.10 * price: 0.10 = 0.91
weight of patterns.trash.Aluminum = 93.0 Total Paper value = 2.37
weight of patterns.trash.Glass = 93.0 Glass weight: 5.40 * price: 0.23 = 1.24
weight of patterns.trash.Paper = 80.0 Glass weight: 4.30 * price: 0.23 = 0.99
weight of patterns.trash.Glass = 36.0 Glass weight: 3.60 * price: 0.23 = 0.83
weight of patterns.trash.Glass = 12.0 Total Glass value = 3.06
weight of patterns.trash.Glass = 60.0 Cardboard weight: 4.40 * price: 0.11 = 0.48
weight of patterns.trash.Paper = 66.0 Cardboard weight: 2.20 * price: 0.11 = 0.24
weight of patterns.trash.Aluminum = 36.0 Cardboard weight: 1.20 * price: 0.11 = 0.13
weight of patterns.trash.Cardboard = 22.0 Total Cardboard value = 0.86
Total value = 1086.0599818825722 Cardboard weight: 4.40 * price: 0.11 = 0.48
Paper weight: 8.00 * price: 0.10 = 0.80
Aluminum weight: 1.80 * price: 1.67 = 3.01
Glass weight: 5.40 * price: 0.23 = 1.24
Aluminum weight: 3.40 * price: 1.67 = 5.68
Cardboard weight: 2.20 * price: 0.11 = 0.24
Glass weight: 4.30 * price: 0.23 = 0.99
Cardboard weight: 1.20 * price: 0.11 = 0.13
Paper weight: 6.60 * price: 0.10 = 0.66
Aluminum weight: 2.70 * price: 1.67 = 4.51
Paper weight: 9.10 * price: 0.10 = 0.91
Glass weight: 3.60 * price: 0.23 = 0.83
Total Trash value = 19.48
*/ */

View File

@ -2,83 +2,105 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Adding more objects to the recycling problem
// {java patterns.recyclec.RecycleC} // {java patterns.recyclec.RecycleC}
package patterns.recyclec; package patterns.recyclec;
import patterns.trash.*; import patterns.trash.*;
import java.util.*; import java.util.*;
// A List that admits only the right type: // A List that only admits the right type:
class Tbin<T extends Trash> extends ArrayList<T> { class
Class<T> binType; TrashBin<T extends Trash> extends ArrayList<T> {
Tbin(Class<T> type) { final Class<T> binType;
binType = type; TrashBin(Class<T> binType) {
this.binType = binType;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
boolean grab(Trash t) { boolean grab(Trash t) {
// Comparing class types: // Compare class types:
if(t.getClass().equals(binType)) { if(t.getClass().equals(binType)) {
add((T)t); // Downcast to this TBin's type add((T)t); // Downcast to this TrashBin type
return true; // Object grabbed return true; // Trash grabbed
} }
return false; // Object not grabbed return false; // Trash not grabbed
} }
} }
class TbinList<T extends Trash> class TrashBinList<T extends Trash>
extends ArrayList<Tbin<? extends T>> { // [1] extends ArrayList<TrashBin<? extends T>> { // [1]
boolean sort(T t) { @SuppressWarnings("unchecked")
for(Tbin<? extends T> ts : this) public TrashBinList(Class<? extends T>... types) {
for(Class<? extends T> type : types)
add(new TrashBin<>(type));
}
public boolean sort(T t) {
for(TrashBin<? extends T> ts : this)
if(ts.grab(t)) if(ts.grab(t))
return true; return true;
return false; // bin not found for t return false; // TrashBin not found for t
} }
void sortBin(Tbin<T> bin) { // [2] public void sortBin(TrashBin<T> bin) { // [2]
for(T aBin : bin) for(T trash : bin)
if(!sort(aBin)) if(!sort(trash))
System.err.println("Bin not found"); throw new RuntimeException(
"Bin not found for " + trash);
}
public void show() {
for(TrashBin<? extends T> tbin : this) {
String typeName = tbin.binType.getSimpleName();
TrashValue.sum(tbin, typeName);
}
} }
} }
public class RecycleC { public class RecycleC {
static Tbin<Trash> bin = new Tbin<>(Trash.class);
public static void main(String[] args) { public static void main(String[] args) {
// Fill up the Trash bin: TrashBin<Trash> bin =
new TrashBin<>(Trash.class);
ParseTrash.fillBin("trash", bin); ParseTrash.fillBin("trash", bin);
@SuppressWarnings("unchecked")
TbinList<Trash> trashBins = new TbinList<>(); TrashBinList<Trash> trashBins =
trashBins.add(new Tbin<>(Aluminum.class)); new TrashBinList<>(
trashBins.add(new Tbin<>(Paper.class)); Aluminum.class, Paper.class, Glass.class,
trashBins.add(new Tbin<>(Glass.class)); // Add one item:
// add one line here: // [3] Cardboard.class // [3]
trashBins.add(new Tbin<>(Cardboard.class)); );
trashBins.sortBin(bin); // [4] trashBins.sortBin(bin); // [4]
trashBins.show();
trashBins.forEach(Trash::sumValue); TrashValue.sum(bin, "Trash");
Trash.sumValue(bin);
} }
} }
/* Output: (First and Last 10 Lines) /* Output:
Loading patterns.trash.Glass Loading patterns.trash.Cardboard
Loading patterns.trash.Paper Loading patterns.trash.Paper
Loading patterns.trash.Aluminum Loading patterns.trash.Aluminum
Loading patterns.trash.Cardboard Loading patterns.trash.Glass
weight of patterns.trash.Aluminum = 89.0 Aluminum weight: 1.80 * price: 1.67 = 3.01
weight of patterns.trash.Aluminum = 76.0 Aluminum weight: 3.40 * price: 1.67 = 5.68
weight of patterns.trash.Aluminum = 25.0 Aluminum weight: 2.70 * price: 1.67 = 4.51
weight of patterns.trash.Aluminum = 34.0 Total Aluminum value = 13.19
weight of patterns.trash.Aluminum = 27.0 Paper weight: 8.00 * price: 0.10 = 0.80
weight of patterns.trash.Aluminum = 18.0 Paper weight: 6.60 * price: 0.10 = 0.66
...________...________...________...________... Paper weight: 9.10 * price: 0.10 = 0.91
weight of patterns.trash.Aluminum = 93.0 Total Paper value = 2.37
weight of patterns.trash.Glass = 93.0 Glass weight: 5.40 * price: 0.23 = 1.24
weight of patterns.trash.Paper = 80.0 Glass weight: 4.30 * price: 0.23 = 0.99
weight of patterns.trash.Glass = 36.0 Glass weight: 3.60 * price: 0.23 = 0.83
weight of patterns.trash.Glass = 12.0 Total Glass value = 3.06
weight of patterns.trash.Glass = 60.0 Cardboard weight: 4.40 * price: 0.11 = 0.48
weight of patterns.trash.Paper = 66.0 Cardboard weight: 2.20 * price: 0.11 = 0.24
weight of patterns.trash.Aluminum = 36.0 Cardboard weight: 1.20 * price: 0.11 = 0.13
weight of patterns.trash.Cardboard = 22.0 Total Cardboard value = 0.86
Total value = 1086.0599818825722 Cardboard weight: 4.40 * price: 0.11 = 0.48
Paper weight: 8.00 * price: 0.10 = 0.80
Aluminum weight: 1.80 * price: 1.67 = 3.01
Glass weight: 5.40 * price: 0.23 = 1.24
Aluminum weight: 3.40 * price: 1.67 = 5.68
Cardboard weight: 2.20 * price: 0.11 = 0.24
Glass weight: 4.30 * price: 0.23 = 0.99
Cardboard weight: 1.20 * price: 0.11 = 0.13
Paper weight: 6.60 * price: 0.10 = 0.66
Aluminum weight: 2.70 * price: 1.67 = 4.51
Paper weight: 9.10 * price: 0.10 = 0.91
Glass weight: 3.60 * price: 0.23 = 0.83
Total Trash value = 19.48
*/ */

View File

@ -2,9 +2,10 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// The StateMachine pattern and Template method // The State Machine pattern.
// {java patterns.state.StateMachineDemo} // {java patterns.state.StateMachineDemo}
package patterns.state; package patterns.state;
import java.util.*;
import onjava.Nap; import onjava.Nap;
interface State { interface State {
@ -16,7 +17,7 @@ abstract class StateMachine {
protected abstract boolean changeState(); protected abstract boolean changeState();
// Template method: // Template method:
protected final void runAll() { protected final void runAll() {
while(changeState()) // Customizable while(changeState())
currentState.run(); currentState.run();
} }
} }
@ -46,20 +47,19 @@ class Rinse implements State {
class Washer extends StateMachine { class Washer extends StateMachine {
private int i = 0; private int i = 0;
// The state table: private Iterator<State> states =
private State[] states = { Arrays.asList(
new Wash(), new Spin(), new Wash(), new Spin(),
new Rinse(), new Spin(), new Rinse(), new Spin()
}; ).iterator();
Washer() { runAll(); } Washer() { runAll(); }
@Override public boolean changeState() { @Override public boolean changeState() {
if(i < states.length) { if(!states.hasNext())
// Change the state by setting the
// surrogate reference to a new object:
currentState = states[i++];
return true;
} else
return false; return false;
// Set the surrogate reference
// to a new State object:
currentState = states.next();
return true;
} }
} }

View File

@ -9,13 +9,14 @@ import java.util.*;
// The common strategy base type: // The common strategy base type:
class FindMinima { class FindMinima {
protected
Function<List<Double>, List<Double>> algorithm; Function<List<Double>, List<Double>> algorithm;
} }
// The various strategies: // The various strategies, each producing dummy data:
class LeastSquares extends FindMinima { class LeastSquares extends FindMinima {
LeastSquares() { LeastSquares() {
// Line is a sequence of points (Dummy data): // Line is a sequence of points:
algorithm = (line) -> Arrays.asList(1.1, 2.2); algorithm = (line) -> Arrays.asList(1.1, 2.2);
} }
} }
@ -35,8 +36,8 @@ class Bisection extends FindMinima {
// The "Context" controls the strategy: // The "Context" controls the strategy:
class MinimaSolver { class MinimaSolver {
private FindMinima strategy; private FindMinima strategy;
MinimaSolver(FindMinima strat) { MinimaSolver(FindMinima strategy) {
strategy = strat; this.strategy = strategy;
} }
List<Double> minima(List<Double> line) { List<Double> minima(List<Double> line) {
return strategy.algorithm.apply(line); return strategy.algorithm.apply(line);
@ -54,11 +55,14 @@ public class StrategyPattern {
1.0, 2.0, 1.0, 2.0, -1.0, 1.0, 2.0, 1.0, 2.0, -1.0,
3.0, 4.0, 5.0, 4.0 ); 3.0, 4.0, 5.0, 4.0 );
System.out.println(solver.minima(line)); System.out.println(solver.minima(line));
solver.changeAlgorithm(new Perturbation());
System.out.println(solver.minima(line));
solver.changeAlgorithm(new Bisection()); solver.changeAlgorithm(new Bisection());
System.out.println(solver.minima(line)); System.out.println(solver.minima(line));
} }
} }
/* Output: /* Output:
[1.1, 2.2] [1.1, 2.2]
[3.3, 4.4]
[5.5, 6.6] [5.5, 6.6]
*/ */

View File

@ -9,6 +9,7 @@ import java.util.*;
// "Context" is now incorporated: // "Context" is now incorporated:
class FindMinima2 { class FindMinima2 {
private
Function<List<Double>, List<Double>> algorithm; Function<List<Double>, List<Double>> algorithm;
FindMinima2() { leastSquares(); } // default FindMinima2() { leastSquares(); } // default
// The various strategies: // The various strategies:
@ -33,11 +34,14 @@ public class StrategyPattern2 {
1.0, 2.0, 1.0, 2.0, -1.0, 1.0, 2.0, 1.0, 2.0, -1.0,
3.0, 4.0, 5.0, 4.0 ); 3.0, 4.0, 5.0, 4.0 );
System.out.println(solver.minima(line)); System.out.println(solver.minima(line));
solver.perturbation();
System.out.println(solver.minima(line));
solver.bisection(); solver.bisection();
System.out.println(solver.minima(line)); System.out.println(solver.minima(line));
} }
} }
/* Output: /* Output:
[1.1, 2.2] [1.1, 2.2]
[3.3, 4.4]
[5.5, 6.6] [5.5, 6.6]
*/ */

View File

@ -5,10 +5,12 @@
package patterns.trash; package patterns.trash;
public class Aluminum extends Trash { public class Aluminum extends Trash {
private static double val = 1.67f;
public Aluminum(double wt) { super(wt); } public Aluminum(double wt) { super(wt); }
@Override public double value() { return val; } @Override public double price() {
public static void value(double newVal) { return Price.ALUMINUM;
val = newVal; }
// Ignore for now; to be used later:
@Override public void accept(Visitor v) {
v.visit(this);
} }
} }

35
patterns/trash/Bins.java Normal file
View File

@ -0,0 +1,35 @@
// patterns/trash/Bins.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package patterns.trash;
import java.util.*;
public class Bins {
final List<Trash> bin;
final List<Aluminum> aluminum = new ArrayList<>();
final List<Paper> paper = new ArrayList<>();
final List<Glass> glass = new ArrayList<>();
final List<Cardboard> cardboard = new ArrayList<>();
public Bins(List<Trash> source) {
bin = new ArrayList<>(source); // Copy
bin.forEach( t -> {
// Use reflection to discover Trash type:
if(t instanceof Aluminum)
aluminum.add((Aluminum)t);
if(t instanceof Paper)
paper.add((Paper)t);
if(t instanceof Glass)
glass.add((Glass)t);
if(t instanceof Cardboard)
cardboard.add((Cardboard)t);
});
}
public void show() {
TrashValue.sum(aluminum, "Aluminum");
TrashValue.sum(paper, "Paper");
TrashValue.sum(glass, "Glass");
TrashValue.sum(cardboard, "Cardboard");
TrashValue.sum(bin, "Trash");
}
}

View File

@ -5,10 +5,12 @@
package patterns.trash; package patterns.trash;
public class Cardboard extends Trash { public class Cardboard extends Trash {
private static double val = 0.23f;
public Cardboard(double wt) { super(wt); } public Cardboard(double wt) { super(wt); }
@Override public double value() { return val; } @Override public double price() {
public static void value(double newVal) { return Price.CARDBOARD;
val = newVal; }
// Ignore for now; to be used later:
@Override public void accept(Visitor v) {
v.visit(this);
} }
} }

View File

@ -0,0 +1,20 @@
// patterns/trash/ClassToListOfTrashMap.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Display a Map<Class, List<Trash>>.
package patterns.trash;
import java.util.*;
public class ClassToListOfTrashMap {
public static void
show(Map<Class, List<Trash>> map) {
map.values().forEach( bin -> {
String typeName = "Trash";
if(!bin.isEmpty())
typeName =
bin.get(0).getClass().getSimpleName();
TrashValue.sum(bin, typeName);
});
}
}

View File

@ -0,0 +1,44 @@
// patterns/trash/DynaFactory.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Dynamic discovery of Trash types.
package patterns.trash;
import java.util.*;
import java.util.function.*;
import java.lang.reflect.*;
public class DynaFactory {
private Map<String, Constructor> constructors =
new HashMap<>();
private String packageName;
public DynaFactory(String packageName) {
this.packageName = packageName;
}
@SuppressWarnings("unchecked")
public
<T extends Trash> T create(TrashInfo info) {
try {
String typename =
"patterns." + packageName + "." + info.type;
return (T)constructors.computeIfAbsent(
typename, this::findConstructor
).newInstance(info.data);
} catch(Exception e) {
throw new RuntimeException(
"Cannot create() Trash: " + info, e);
}
}
private
Constructor findConstructor(String typename) {
try {
System.out.println("Loading " + typename);
return Class.forName(typename)
.getConstructor(double.class);
} catch(Exception e) {
throw new RuntimeException(
"Trash(double) Constructor Not Found: " +
typename, e);
}
}
}

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Any object that can be filled with Trash // Any object that can be filled with Trash.
package patterns.trash; package patterns.trash;
public interface Fillable<T extends Trash> { public interface Fillable<T extends Trash> {

View File

@ -2,15 +2,17 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Adapter that makes a List Fillable // Adapter that makes a List Fillable.
package patterns.trash; package patterns.trash;
import java.util.*; import java.util.*;
public class FillableList<T extends Trash> public class FillableList<T extends Trash>
implements Fillable<T> { implements Fillable<T> {
private List<T> v; private List<T> list;
public FillableList(List<T> vv) { public FillableList(List<T> list) {
v = vv; this.list = list;
}
@Override public void addTrash(T t) {
list.add(t);
} }
@Override public void addTrash(T t) { v.add(t); }
} }

View File

@ -5,10 +5,12 @@
package patterns.trash; package patterns.trash;
public class Glass extends Trash { public class Glass extends Trash {
private static double val = 0.23f;
public Glass(double wt) { super(wt); } public Glass(double wt) { super(wt); }
@Override public double value() { return val; } @Override public double price() {
public static void value(double newVal) { return Price.GLASS;
val = newVal; }
// Ignore for now; to be used later:
@Override public void accept(Visitor v) {
v.visit(this);
} }
} }

View File

@ -0,0 +1,41 @@
// patterns/trash/GroupingBy.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {java patterns.trash.GroupingBy}
package patterns.trash;
import java.util.*;
import java.util.stream.*;
public class GroupingBy {
public static void main(String[] args) {
List<Trash> bin = new ArrayList<>();
ParseTrash.fillBin("trash", bin);
Map<Class, List<Trash>> m =
bin.stream().collect(
Collectors.groupingBy(Object::getClass));
ClassToListOfTrashMap.show(m);
}
}
/* Output:
Loading patterns.trash.Cardboard
Loading patterns.trash.Paper
Loading patterns.trash.Aluminum
Loading patterns.trash.Glass
Glass weight: 5.40 * price: 0.23 = 1.24
Glass weight: 4.30 * price: 0.23 = 0.99
Glass weight: 3.60 * price: 0.23 = 0.83
Total Glass value = 3.06
Paper weight: 8.00 * price: 0.10 = 0.80
Paper weight: 6.60 * price: 0.10 = 0.66
Paper weight: 9.10 * price: 0.10 = 0.91
Total Paper value = 2.37
Cardboard weight: 4.40 * price: 0.11 = 0.48
Cardboard weight: 2.20 * price: 0.11 = 0.24
Cardboard weight: 1.20 * price: 0.11 = 0.13
Total Cardboard value = 0.86
Aluminum weight: 1.80 * price: 1.67 = 3.01
Aluminum weight: 3.40 * price: 1.67 = 5.68
Aluminum weight: 2.70 * price: 1.67 = 4.51
Total Aluminum value = 13.19
*/

View File

@ -5,10 +5,12 @@
package patterns.trash; package patterns.trash;
public class Paper extends Trash { public class Paper extends Trash {
private static double val = 0.10f;
public Paper(double wt) { super(wt); } public Paper(double wt) { super(wt); }
@Override public double value() { return val; } @Override public double price() {
public static void value(double newVal) { return Price.PAPER;
val = newVal; }
// Ignore for now; to be used later:
@Override public void accept(Visitor v) {
v.visit(this);
} }
} }

View File

@ -2,8 +2,8 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Open a file and parse its contents into // Opens a file and parses its contents into
// Trash objects, placing each into a List // Trash objects, placing each into a Fillable.
// {java patterns.trash.ParseTrash} // {java patterns.trash.ParseTrash}
package patterns.trash; package patterns.trash;
import java.util.*; import java.util.*;
@ -13,79 +13,56 @@ import java.nio.file.*;
import java.nio.file.Files; import java.nio.file.Files;
public class ParseTrash { public class ParseTrash {
public static String source = "Trash.dat";
public static <T extends Trash> void public static <T extends Trash> void
fillBin(String pckg, Fillable<T> bin) { fillBin(String packageName, Fillable<T> bin) {
DynaFactory factory =
new DynaFactory(packageName);
try { try {
Files.lines(Paths.get("trash", "Trash.dat")) Files.lines(Paths.get("trash", source))
// Remove empty lines and comment lines: // Remove comments and empty lines:
.filter(line -> line.trim().length() != 0) .filter(line -> line.trim().length() != 0)
.filter(line -> !line.startsWith("//")) .filter(line -> !line.startsWith("//"))
.forEach( line -> { .forEach(line -> {
String type = "patterns." + pckg + "." + String type = line.substring(
line.substring(
0, line.indexOf(':')).trim(); 0, line.indexOf(':')).trim();
double weight = Double.valueOf( double weight = Double.valueOf(
line.substring(line.indexOf(':') + 1) line.substring(line.indexOf(':') + 1)
.trim()); .trim());
bin.addTrash(Trash.factory( bin.addTrash(factory.create(
new Trash.Info(type, weight))); new TrashInfo(type, weight)));
}); });
} catch(IOException | } catch(IOException | NumberFormatException e) {
NumberFormatException |
Trash.TrashClassNotFoundException |
Trash.CannotCreateTrashException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
// Special case to handle List: // Special case to handle a List:
public static <T extends Trash> void public static <T extends Trash> void
fillBin(String pckg, List<T> bin) { fillBin(String packageName, List<T> bin) {
fillBin(pckg, new FillableList<>(bin)); fillBin(packageName, new FillableList<>(bin));
} }
// Basic test: // Basic test:
public static void main(String[] args) { public static void main(String[] args) {
List<Trash> t = new ArrayList<>(); List<Trash> bin = new ArrayList<>();
fillBin("trash", t); fillBin("trash", bin);
t.forEach(System.out::println); bin.forEach(System.out::println);
} }
} }
/* Output: /* Output:
Loading patterns.trash.Glass Loading patterns.trash.Cardboard
Loading patterns.trash.Paper Loading patterns.trash.Paper
Loading patterns.trash.Aluminum Loading patterns.trash.Aluminum
Loading patterns.trash.Cardboard Loading patterns.trash.Glass
patterns.trash.Glass w:54.0 v:0.23 Cardboard weight: 4.40 * price: 0.11 = 0.48
patterns.trash.Paper w:22.0 v:0.10 Paper weight: 8.00 * price: 0.10 = 0.80
patterns.trash.Paper w:11.0 v:0.10 Aluminum weight: 1.80 * price: 1.67 = 3.01
patterns.trash.Glass w:17.0 v:0.23 Glass weight: 5.40 * price: 0.23 = 1.24
patterns.trash.Aluminum w:89.0 v:1.67 Aluminum weight: 3.40 * price: 1.67 = 5.68
patterns.trash.Paper w:88.0 v:0.10 Cardboard weight: 2.20 * price: 0.11 = 0.24
patterns.trash.Aluminum w:76.0 v:1.67 Glass weight: 4.30 * price: 0.23 = 0.99
patterns.trash.Cardboard w:96.0 v:0.23 Cardboard weight: 1.20 * price: 0.11 = 0.13
patterns.trash.Aluminum w:25.0 v:1.67 Paper weight: 6.60 * price: 0.10 = 0.66
patterns.trash.Aluminum w:34.0 v:1.67 Aluminum weight: 2.70 * price: 1.67 = 4.51
patterns.trash.Glass w:11.0 v:0.23 Paper weight: 9.10 * price: 0.10 = 0.91
patterns.trash.Glass w:68.0 v:0.23 Glass weight: 3.60 * price: 0.23 = 0.83
patterns.trash.Glass w:43.0 v:0.23
patterns.trash.Aluminum w:27.0 v:1.67
patterns.trash.Cardboard w:44.0 v:0.23
patterns.trash.Aluminum w:18.0 v:1.67
patterns.trash.Paper w:91.0 v:0.10
patterns.trash.Glass w:63.0 v:0.23
patterns.trash.Glass w:50.0 v:0.23
patterns.trash.Glass w:80.0 v:0.23
patterns.trash.Aluminum w:81.0 v:1.67
patterns.trash.Cardboard w:12.0 v:0.23
patterns.trash.Glass w:12.0 v:0.23
patterns.trash.Glass w:54.0 v:0.23
patterns.trash.Aluminum w:36.0 v:1.67
patterns.trash.Aluminum w:93.0 v:1.67
patterns.trash.Glass w:93.0 v:0.23
patterns.trash.Paper w:80.0 v:0.10
patterns.trash.Glass w:36.0 v:0.23
patterns.trash.Glass w:12.0 v:0.23
patterns.trash.Glass w:60.0 v:0.23
patterns.trash.Paper w:66.0 v:0.10
patterns.trash.Aluminum w:36.0 v:1.67
patterns.trash.Cardboard w:22.0 v:0.23
*/ */

13
patterns/trash/Price.java Normal file
View File

@ -0,0 +1,13 @@
// patterns/trash/Price.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package patterns.trash;
public interface Price {
double
ALUMINUM = 1.67,
PAPER = 0.10,
GLASS = 0.23,
CARDBOARD = 0.11;
}

View File

@ -1,35 +1,13 @@
// patterns/trash/Trash.dat // patterns/trash/Trash.dat
Glass:54 Cardboard:4.4
Paper:22 Paper:8.0
Paper:11 Aluminum:1.8
Glass:17 Glass:5.4
Aluminum:89 Aluminum:3.4
Paper:88 Cardboard:2.2
Aluminum:76 Glass:4.3
Cardboard:96 Cardboard:1.2
Aluminum:25 Paper:6.6
Aluminum:34 Aluminum:2.7
Glass:11 Paper:9.1
Glass:68 Glass:3.6
Glass:43
Aluminum:27
Cardboard:44
Aluminum:18
Paper:91
Glass:63
Glass:50
Glass:80
Aluminum:81
Cardboard:12
Glass:12
Glass:54
Aluminum:36
Aluminum:93
Glass:93
Paper:80
Glass:36
Glass:12
Glass:60
Paper:66
Aluminum:36
Cardboard:22

View File

@ -2,90 +2,21 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Base class for Trash recycling examples // Base class for Trash recycling examples.
package patterns.trash; package patterns.trash;
import java.util.*;
import java.lang.reflect.*;
public abstract class Trash { public abstract class Trash {
private double weight; public final double weight;
public Trash(double wt) { weight = wt; } public Trash(double weight) {
public Trash() {} this.weight = weight;
public abstract double value();
public double weight() { return weight; }
// Sums the value of Trash in a bin:
static double val;
public static <T extends Trash>
void sumValue(List<? extends T> bin) {
val = 0.0f;
bin.forEach( t -> {
val += t.weight() * t.value();
System.out.println("weight of " +
// RTTI gets type information
// about the class:
t.getClass().getName() +
" = " + t.weight());
});
System.out.println("Total value = " + val);
} }
public abstract double price();
@Override public String toString() { @Override public String toString() {
// Print correct subclass name: return String.format(
return getClass().getName() + "%s weight: %.2f * price: %.2f = %.2f",
" w:" + weight() + " v:" + getClass().getSimpleName(),
String.format("%.2f", value()); weight, price(), weight * price());
}
// Remainder of class supports dynamic creation:
public static class CannotCreateTrashException
extends RuntimeException {
public CannotCreateTrashException(Exception why) {
super(why);
}
}
public static class TrashClassNotFoundException
extends RuntimeException {
public TrashClassNotFoundException(Exception why) {
super(why);
}
}
public static class Info {
public String id;
public double data;
public Info(String name, double data) {
id = name;
this.data = data;
}
}
private static List<Class> trashTypes =
new ArrayList<>();
@SuppressWarnings("unchecked")
public static <T extends Trash> T factory(Info info) {
for(Class trashType : trashTypes) {
// Determine the type and create one:
if(trashType.getName().contains(info.id)) {
try {
// Get the dynamic constructor method
// that takes a double argument:
Constructor ctor =
trashType.getConstructor(double.class);
// Call the constructor to create a
// new object:
return
(T)ctor.newInstance(info.data);
} catch(Exception e) {
throw new CannotCreateTrashException(e);
}
}
}
// The necessary Class was not in the list. Try to
// load it, but it must be in your class path!
try {
System.out.println("Loading " + info.id);
trashTypes.add(Class.forName(info.id));
} catch(Exception e) {
throw new TrashClassNotFoundException(e);
}
// Loaded successfully. Recursive call
// should work this time:
return factory(info);
} }
// Ignore for now; to be used later:
public abstract void accept(Visitor v);
} }

View File

@ -0,0 +1,18 @@
// patterns/trash/TrashInfo.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Messenger class carrying Trash creation data.
package patterns.trash;
public class TrashInfo {
public final String type;
public final double data;
public TrashInfo(String type, double data) {
this.type = type;
this.data = data;
}
@Override public String toString() {
return "TrashInfo(" + type + ", " + data + ")";
}
}

View File

@ -0,0 +1,21 @@
// patterns/trash/TrashValue.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Sums the value of Trash in a bin.
package patterns.trash;
import java.util.*;
public class TrashValue {
private static double total;
public static void
sum(List<? extends Trash> bin, String type) {
total = 0.0;
bin.forEach( t -> {
System.out.println(t);
total += t.weight * t.price();
});
System.out.printf(
"Total %s value = %.2f%n", type, total);
}
}

View File

@ -0,0 +1,104 @@
// patterns/trash/TrashVisitor.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Related algorithms packaged in
// each implementation of Visitor.
// {java patterns.trash.TrashVisitor}
package patterns.trash;
import java.util.*;
class PriceVisitor extends Visitor {
public PriceVisitor() { super("price"); }
@Override public void visit(Aluminum al) {
double price = al.weight * al.price();
show("Aluminum", price);
alTotal += price;
}
@Override public void visit(Paper p) {
double price = p.weight * p.price();
show("Paper", price);
pTotal += price;
}
@Override public void visit(Glass g) {
double price = g.weight * g.price();
show("Glass", price);
gTotal += price;
}
@Override public void visit(Cardboard c) {
double price = c.weight * c.price();
show("Cardboard", price);
cTotal += price;
}
}
class WeightVisitor extends Visitor {
public WeightVisitor() { super("weight"); }
@Override public void visit(Aluminum al) {
show("Aluminum", al.weight);
alTotal += al.weight;
}
@Override public void visit(Paper p) {
show("Paper", p.weight);
pTotal += p.weight;
}
@Override public void visit(Glass g) {
show("Glass", g.weight);
gTotal += g.weight;
}
@Override public void visit(Cardboard c) {
show("Cardboard", c.weight);
cTotal += c.weight;
}
}
public class TrashVisitor {
public static void main(String[] args) {
List<Trash> bin = new ArrayList<>();
ParseTrash.fillBin("trash", bin);
List<Visitor> visitors = Arrays.asList(
new PriceVisitor(), new WeightVisitor());
bin.forEach(
trash -> visitors.forEach(trash::accept)
);
visitors.forEach(Visitor::total);
}
}
/* Output:
Loading patterns.trash.Cardboard
Loading patterns.trash.Paper
Loading patterns.trash.Aluminum
Loading patterns.trash.Glass
Cardboard price: 0.48
Cardboard weight: 4.40
Paper price: 0.80
Paper weight: 8.00
Aluminum price: 3.01
Aluminum weight: 1.80
Glass price: 1.24
Glass weight: 5.40
Aluminum price: 5.68
Aluminum weight: 3.40
Cardboard price: 0.24
Cardboard weight: 2.20
Glass price: 0.99
Glass weight: 4.30
Cardboard price: 0.13
Cardboard weight: 1.20
Paper price: 0.66
Paper weight: 6.60
Aluminum price: 4.51
Aluminum weight: 2.70
Paper price: 0.91
Paper weight: 9.10
Glass price: 0.83
Glass weight: 3.60
Total Aluminum price: 13.19
Total Paper price: 2.37
Total Glass price: 3.06
Total Cardboard price: 0.86
Total Aluminum weight: 7.90
Total Paper weight: 23.70
Total Glass weight: 13.30
Total Cardboard weight: 7.80
*/

View File

@ -0,0 +1,52 @@
// patterns/trash/TypeMapTrash.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Using a Map of Lists and reflection to sort
// Trash into Lists. This is extensible, despite
// the use of reflection.
// {java patterns.trash.TypeMapTrash}
package patterns.trash;
import patterns.TypeMap;
// Adapter class for ParseTrash.fillBin():
class TypeMapAdapter implements Fillable {
private TypeMap<Trash> map;
TypeMapAdapter(TypeMap<Trash> map) {
this.map = map;
}
@Override
public void addTrash(Trash t) { map.add(t); }
}
public class TypeMapTrash {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
TypeMap<Trash> bin = new TypeMap<>();
ParseTrash.fillBin(
"trash", new TypeMapAdapter(bin));
ClassToListOfTrashMap.show(bin.map);
}
}
/* Output:
Loading patterns.trash.Cardboard
Loading patterns.trash.Paper
Loading patterns.trash.Aluminum
Loading patterns.trash.Glass
Paper weight: 8.00 * price: 0.10 = 0.80
Paper weight: 6.60 * price: 0.10 = 0.66
Paper weight: 9.10 * price: 0.10 = 0.91
Total Paper value = 2.37
Glass weight: 5.40 * price: 0.23 = 1.24
Glass weight: 4.30 * price: 0.23 = 0.99
Glass weight: 3.60 * price: 0.23 = 0.83
Total Glass value = 3.06
Aluminum weight: 1.80 * price: 1.67 = 3.01
Aluminum weight: 3.40 * price: 1.67 = 5.68
Aluminum weight: 2.70 * price: 1.67 = 4.51
Total Aluminum value = 13.19
Cardboard weight: 4.40 * price: 0.11 = 0.48
Cardboard weight: 2.20 * price: 0.11 = 0.24
Cardboard weight: 1.20 * price: 0.11 = 0.13
Total Cardboard value = 0.86
*/

View File

@ -0,0 +1,31 @@
// patterns/trash/Visitor.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// The base class for Visitors.
package patterns.trash;
public abstract class Visitor {
protected double alTotal; // Aluminum
protected double pTotal; // Paper
protected double gTotal; // Glass
protected double cTotal; // Cardboard
protected String descriptor;
protected Visitor(String descriptor) {
this.descriptor = descriptor;
}
protected void show(String type, double value) {
System.out.printf(
"%s %s: %.2f%n", type, descriptor, value);
}
public void total() {
show("Total Aluminum", alTotal);
show("Total Paper", pTotal);
show("Total Glass", gTotal);
show("Total Cardboard", cTotal);
}
abstract void visit(Aluminum a);
abstract void visit(Paper p);
abstract void visit(Glass g);
abstract void visit(Cardboard c);
}

View File

@ -1,15 +0,0 @@
// patterns/trashvisitor/Aluminum.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Aluminum for the visitor pattern
package patterns.trashvisitor;
import patterns.trash.*;
public class Aluminum extends patterns.trash.Aluminum
implements Visitable {
public Aluminum(double wt) { super(wt); }
@Override public void accept(Visitor v) {
v.visit(this);
}
}

View File

@ -1,15 +0,0 @@
// patterns/trashvisitor/Cardboard.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Cardboard for the visitor pattern
package patterns.trashvisitor;
import patterns.trash.*;
public class Cardboard extends patterns.trash.Cardboard
implements Visitable {
public Cardboard(double wt) { super(wt); }
@Override public void accept(Visitor v) {
v.visit(this);
}
}

View File

@ -1,15 +0,0 @@
// patterns/trashvisitor/Glass.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Glass for the visitor pattern
package patterns.trashvisitor;
import patterns.trash.*;
public class Glass extends patterns.trash.Glass
implements Visitable {
public Glass(double wt) { super(wt); }
@Override public void accept(Visitor v) {
v.visit(this);
}
}

View File

@ -1,15 +0,0 @@
// patterns/trashvisitor/Paper.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Paper for the visitor pattern
package patterns.trashvisitor;
import patterns.trash.*;
public class Paper extends patterns.trash.Paper
implements Visitable {
public Paper(double wt) { super(wt); }
@Override public void accept(Visitor v) {
v.visit(this);
}
}

View File

@ -1,117 +0,0 @@
// patterns/trashvisitor/TrashVisitor.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {java patterns.trashvisitor.TrashVisitor}
package patterns.trashvisitor;
import patterns.trash.*;
import java.util.*;
// Specific group of algorithms packaged
// in each implementation of Visitor:
class PriceVisitor implements Visitor {
private double alSum; // Aluminum
private double pSum; // Paper
private double gSum; // Glass
private double cSum; // Cardboard
public static void show(String s) {
System.out.println(s);
}
@Override public void visit(Aluminum al) {
double v = al.weight() * al.value();
show("value of Aluminum= " + v);
alSum += v;
}
@Override public void visit(Paper p) {
double v = p.weight() * p.value();
show("value of Paper= " + v);
pSum += v;
}
@Override public void visit(Glass g) {
double v = g.weight() * g.value();
show("value of Glass= " + v);
gSum += v;
}
@Override public void visit(Cardboard c) {
double v = c.weight() * c.value();
show("value of Cardboard = " + v);
cSum += v;
}
@Override public void total() {
show(
"Total Aluminum: $" + alSum + "\n" +
"Total Paper: $" + pSum + "\n" +
"Total Glass: $" + gSum + "\n" +
"Total Cardboard: $" + cSum);
}
}
class WeightVisitor implements Visitor {
private double alSum; // Aluminum
private double pSum; // Paper
private double gSum; // Glass
private double cSum; // Cardboard
public static void show(String s) {
System.out.println(s);
}
@Override public void visit(Aluminum al) {
alSum += al.weight();
show("Aluminum weight = " + al.weight());
}
@Override public void visit(Paper p) {
pSum += p.weight();
show("Paper weight = " + p.weight());
}
@Override public void visit(Glass g) {
gSum += g.weight();
show("Glass weight = " + g.weight());
}
@Override public void visit(Cardboard c) {
cSum += c.weight();
show("Cardboard weight = " + c.weight());
}
@Override public void total() {
show("Total weight Aluminum:" + alSum);
show("Total weight Paper:" + pSum);
show("Total weight Glass:" + gSum);
show("Total weight Cardboard:" + cSum);
}
}
public class TrashVisitor {
public static void main(String[] args) {
List<Trash> bin = new ArrayList<>();
// ParseTrash still works, without changes:
ParseTrash.fillBin("trashvisitor", bin);
List<Visitor> visitors = Arrays.asList(
new PriceVisitor(), new WeightVisitor());
bin.forEach( t -> {
Visitable v = (Visitable) t;
visitors.forEach(visitor -> v.accept(visitor));
});
visitors.forEach(Visitor::total);
}
}
/* Output: (First and Last 10 Lines)
Loading patterns.trashvisitor.Glass
Loading patterns.trashvisitor.Paper
Loading patterns.trashvisitor.Aluminum
Loading patterns.trashvisitor.Cardboard
value of Glass= 12.420000225305557
Glass weight = 54.0
value of Paper= 2.2000000327825546
Paper weight = 22.0
value of Paper= 1.1000000163912773
Paper weight = 11.0
...________...________...________...________...
value of Cardboard = 5.060000091791153
Cardboard weight = 22.0
Total Aluminum: $860.0499778985977
Total Paper: $35.80000053346157
Total Glass: $150.1900027245283
Total Cardboard: $40.02000072598457
Total weight Aluminum:515.0
Total weight Paper:358.0
Total weight Glass:653.0
Total weight Cardboard:174.0
*/

View File

@ -1,12 +0,0 @@
// patterns/trashvisitor/Visitable.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// An interface to add visitor functionality to the
// Trash hierarchy without modifying the base class
package patterns.trashvisitor;
public interface Visitable {
// The new method:
void accept(Visitor v);
}

View File

@ -1,14 +0,0 @@
// patterns/trashvisitor/Visitor.java
// (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// The base interface for visitors
package patterns.trashvisitor;
public interface Visitor {
void visit(Aluminum a);
void visit(Paper p);
void visit(Glass g);
void visit(Cardboard c);
void total();
}

View File

@ -2,7 +2,7 @@
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Demonstration of "visitor" pattern // Demonstration of the Visitor pattern.
// {java patterns.visitor.BeeAndFlowers} // {java patterns.visitor.BeeAndFlowers}
package patterns.visitor; package patterns.visitor;
import java.util.*; import java.util.*;
@ -11,7 +11,7 @@ import java.util.stream.*;
interface Visitor { interface Visitor {
void visit(Gladiolus g); void visit(Gladiolus g);
void visit(Renuculus r); void visit(Ranunculus r);
void visit(Chrysanthemum c); void visit(Chrysanthemum c);
} }
@ -25,7 +25,7 @@ class Gladiolus implements Flower {
public void accept(Visitor v) { v.visit(this);} public void accept(Visitor v) { v.visit(this);}
} }
class Renuculus implements Flower { class Ranunculus implements Flower {
@Override @Override
public void accept(Visitor v) { v.visit(this);} public void accept(Visitor v) { v.visit(this);}
} }
@ -37,13 +37,13 @@ class Chrysanthemum implements Flower {
// Add the ability to produce a String: // Add the ability to produce a String:
class StringVal implements Visitor { class StringVal implements Visitor {
String s; private String s;
@Override public String toString() { return s; } @Override public String toString() { return s; }
@Override public void visit(Gladiolus g) { @Override public void visit(Gladiolus g) {
s = "Gladiolus"; s = "Gladiolus";
} }
@Override public void visit(Renuculus r) { @Override public void visit(Ranunculus r) {
s = "Renuculus"; s = "Ranunculus";
} }
@Override public void visit(Chrysanthemum c) { @Override public void visit(Chrysanthemum c) {
s = "Chrysanthemum"; s = "Chrysanthemum";
@ -55,8 +55,8 @@ class Bee implements Visitor {
@Override public void visit(Gladiolus g) { @Override public void visit(Gladiolus g) {
System.out.println("Bee and Gladiolus"); System.out.println("Bee and Gladiolus");
} }
@Override public void visit(Renuculus r) { @Override public void visit(Ranunculus r) {
System.out.println("Bee and Renuculus"); System.out.println("Bee and Ranunculus");
} }
@Override public void visit(Chrysanthemum c) { @Override public void visit(Chrysanthemum c) {
System.out.println("Bee and Chrysanthemum"); System.out.println("Bee and Chrysanthemum");
@ -66,7 +66,7 @@ class Bee implements Visitor {
class FlowerFactory { class FlowerFactory {
static List<Supplier<Flower>> flowers = static List<Supplier<Flower>> flowers =
Arrays.asList(Gladiolus::new, Arrays.asList(Gladiolus::new,
Renuculus::new, Chrysanthemum::new); Ranunculus::new, Chrysanthemum::new);
static final int SZ = flowers.size(); static final int SZ = flowers.size();
private static SplittableRandom rand = private static SplittableRandom rand =
new SplittableRandom(47); new SplittableRandom(47);
@ -95,21 +95,21 @@ public class BeeAndFlowers {
Gladiolus Gladiolus
Chrysanthemum Chrysanthemum
Gladiolus Gladiolus
Renuculus Ranunculus
Chrysanthemum Chrysanthemum
Renuculus Ranunculus
Chrysanthemum Chrysanthemum
Chrysanthemum Chrysanthemum
Chrysanthemum Chrysanthemum
Renuculus Ranunculus
Bee and Gladiolus Bee and Gladiolus
Bee and Chrysanthemum Bee and Chrysanthemum
Bee and Gladiolus Bee and Gladiolus
Bee and Renuculus Bee and Ranunculus
Bee and Chrysanthemum Bee and Chrysanthemum
Bee and Renuculus Bee and Ranunculus
Bee and Chrysanthemum Bee and Chrysanthemum
Bee and Chrysanthemum Bee and Chrysanthemum
Bee and Chrysanthemum Bee and Chrysanthemum
Bee and Renuculus Bee and Ranunculus
*/ */

View File

@ -1,8 +1,7 @@
// polymorphism/RTTI.java // polymorphism/Reflect.java
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Downcasting & Runtime type information (RTTI)
// {ThrowsException} // {ThrowsException}
class Useful { class Useful {
@ -18,7 +17,7 @@ class MoreUseful extends Useful {
public void w() {} public void w() {}
} }
public class RTTI { public class Reflect {
public static void main(String[] args) { public static void main(String[] args) {
Useful[] x = { Useful[] x = {
new Useful(), new Useful(),
@ -28,7 +27,7 @@ public class RTTI {
x[1].g(); x[1].g();
// Compile time: method not found in Useful: // Compile time: method not found in Useful:
//- x[1].u(); //- x[1].u();
((MoreUseful)x[1]).u(); // Downcast/RTTI ((MoreUseful)x[1]).u(); // Downcast/Reflect
((MoreUseful)x[0]).u(); // Exception thrown ((MoreUseful)x[0]).u(); // Exception thrown
} }
} }
@ -37,5 +36,5 @@ ___[ Error Output ]___
Exception in thread "main" Exception in thread "main"
java.lang.ClassCastException: Useful cannot be cast to java.lang.ClassCastException: Useful cannot be cast to
MoreUseful MoreUseful
at RTTI.main(RTTI.java:29) at Reflect.main(Reflect.java:28)
*/ */

View File

@ -13,7 +13,7 @@ class FruitQualities {
private int ripeness; private int ripeness;
private int smell; private int smell;
// etc. // etc.
// No-arg constructor: // Zero-argument constructor:
FruitQualities() { FruitQualities() {
// Do something meaningful... // Do something meaningful...
} }
@ -32,7 +32,7 @@ class FruitQualities {
class Seed { class Seed {
// Members... // Members...
Seed() { /* No-arg constructor */ } Seed() { /* Zero-argument constructor */ }
Seed(Seed s) { /* Copy constructor */ } Seed(Seed s) { /* Copy constructor */ }
} }
@ -81,7 +81,7 @@ class Tomato extends Fruit {
class ZebraQualities extends FruitQualities { class ZebraQualities extends FruitQualities {
private int stripedness; private int stripedness;
// No-arg constructor: // Zero-argument constructor:
ZebraQualities() { ZebraQualities() {
super(); super();
// do something meaningful... // do something meaningful...
@ -117,7 +117,7 @@ public class CopyConstructor {
t.getClass().getName()); t.getClass().getName());
} }
public static void slice(Fruit f) { public static void slice(Fruit f) {
f = new Fruit(f); // Hmmm... will this work? // [2] f = new Fruit(f); // Hmm... will this work? // [2]
System.out.println("In slice, f is a " + System.out.println("In slice, f is a " +
f.getClass().getName()); f.getClass().getName());
} }

View File

@ -1,9 +1,9 @@
// typeinfo/AnonymousImplementation.java // reflection/AnonymousImplementation.java
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Anonymous inner classes can't hide from reflection // Anonymous inner classes can't hide from reflection
import typeinfo.interfacea.*; import reflection.interfacea.*;
class AnonymousA { class AnonymousA {
public static A makeA() { public static A makeA() {

View File

@ -1,4 +1,4 @@
// typeinfo/BoundedClassReferences.java // reflection/BoundedClassReferences.java
// (c)2021 MindView LLC: see Copyright.txt // (c)2021 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.

Some files were not shown because too many files have changed in this diff Show More