March 2021 Book Update
See notes in "Foreword to the Leanpub Edition"
This commit is contained in:
parent
129df0b752
commit
ede3954d86
@ -33,7 +33,7 @@ class ReversibleArrayList<T> extends ArrayList<T> {
|
||||
public class AdapterMethodIdiom {
|
||||
public static void main(String[] args) {
|
||||
ReversibleArrayList<String> ral =
|
||||
new ReversibleArrayList<String>(
|
||||
new ReversibleArrayList<>(
|
||||
Arrays.asList("To be or not to be".split(" ")));
|
||||
// Grabs the ordinary iterator via iterator():
|
||||
for(String s : ral)
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
public class CollectionSequence
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
public class CrossCollectionIteration {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
public class CrossCollectionIteration2 {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
public class InterfaceVsIterator {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
public class LinkedListFeatures {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ListFeatures {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ListIteration {
|
||||
|
@ -4,7 +4,7 @@
|
||||
// Visit http://OnJava8.com for more book information.
|
||||
// {java collections.MapOfList}
|
||||
package collections;
|
||||
import typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
public class MapOfList {
|
||||
|
@ -29,7 +29,7 @@ public class MultiIterableClass extends IterableClass {
|
||||
return new Iterable<String>() {
|
||||
public Iterator<String> iterator() {
|
||||
List<String> shuffled =
|
||||
new ArrayList<String>(Arrays.asList(words));
|
||||
new ArrayList<>(Arrays.asList(words));
|
||||
Collections.shuffle(shuffled, new Random(47));
|
||||
return shuffled.iterator();
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
class PetSequence {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
public class PetMap {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
public class SimpleIteration {
|
||||
|
@ -56,8 +56,7 @@ public class CollectionMethods {
|
||||
// c2 and c3 (an intersection of sets):
|
||||
c2.retainAll(c3);
|
||||
show(c2);
|
||||
// Throw away all the elements
|
||||
// in c2 that also appear in c3:
|
||||
// Discard all c2 elements that also appear in c3:
|
||||
c2.removeAll(c3);
|
||||
System.out.println(
|
||||
"c2.isEmpty() = " + c2.isEmpty());
|
||||
|
@ -1,12 +1,512 @@
|
||||
0: ForkJoinPool.commonPool-worker-1
|
||||
0: main
|
||||
1: main
|
||||
1: ForkJoinPool.commonPool-worker-3
|
||||
1: ForkJoinPool.commonPool-worker-5
|
||||
3: ForkJoinPool.commonPool-worker-5
|
||||
2: main
|
||||
2: ForkJoinPool.commonPool-worker-1
|
||||
3: main
|
||||
5: ForkJoinPool.commonPool-worker-5
|
||||
4: ForkJoinPool.commonPool-worker-1
|
||||
5: main
|
||||
7: ForkJoinPool.commonPool-worker-5
|
||||
8: main
|
||||
8: ForkJoinPool.commonPool-worker-3
|
||||
10: ForkJoinPool.commonPool-worker-5
|
||||
6: ForkJoinPool.commonPool-worker-1
|
||||
7: main
|
||||
9: ForkJoinPool.commonPool-worker-1
|
||||
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
|
||||
|
@ -26,7 +26,7 @@ class Mail {
|
||||
public String details() {
|
||||
return toString() +
|
||||
", General Delivery: " + generalDelivery +
|
||||
", Address Scanability: " + scannability +
|
||||
", Address Scannability: " + scannability +
|
||||
", Address Readability: " + readability +
|
||||
", Address Address: " + address +
|
||||
", Return address: " + returnAddress;
|
||||
@ -138,52 +138,52 @@ public class PostOffice {
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
Mail 0, General Delivery: NO2, Address Scanability:
|
||||
Mail 0, General Delivery: NO2, Address Scannability:
|
||||
UNSCANNABLE, Address Readability: YES3, Address
|
||||
Address: OK1, Return address: OK1
|
||||
Delivering Mail 0 normally
|
||||
*****
|
||||
Mail 1, General Delivery: NO5, Address Scanability:
|
||||
Mail 1, General Delivery: NO5, Address Scannability:
|
||||
YES3, Address Readability: ILLEGIBLE, Address Address:
|
||||
OK5, Return address: OK1
|
||||
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,
|
||||
Return address: OK5
|
||||
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:
|
||||
INCORRECT, Return address: OK4
|
||||
Returning Mail 3 to sender
|
||||
*****
|
||||
Mail 4, General Delivery: NO4, Address Scanability:
|
||||
Mail 4, General Delivery: NO4, Address Scannability:
|
||||
UNSCANNABLE, Address Readability: YES1, Address
|
||||
Address: INCORRECT, Return address: OK2
|
||||
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:
|
||||
OK4, Return address: OK2
|
||||
Delivering Mail 5 automatically
|
||||
*****
|
||||
Mail 6, General Delivery: YES, Address Scanability:
|
||||
Mail 6, General Delivery: YES, Address Scannability:
|
||||
YES4, Address Readability: ILLEGIBLE, Address Address:
|
||||
OK4, Return address: OK4
|
||||
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,
|
||||
Return address: MISSING
|
||||
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:
|
||||
INCORRECT, Return address: MISSING
|
||||
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
|
||||
Address: OK1, Return address: OK4
|
||||
Delivering Mail 9 normally
|
||||
|
@ -11,7 +11,7 @@ public interface Food {
|
||||
}
|
||||
enum MainCourse implements Food {
|
||||
LASAGNE, BURRITO, PAD_THAI,
|
||||
LENTILS, HUMMOUS, VINDALOO;
|
||||
LENTILS, HUMMUS, VINDALOO;
|
||||
}
|
||||
enum Dessert implements Food {
|
||||
TIRAMISU, GELATO, BLACK_FOREST_CAKE,
|
||||
|
@ -21,7 +21,7 @@ public enum Meal2 {
|
||||
}
|
||||
enum MainCourse implements Food {
|
||||
LASAGNE, BURRITO, PAD_THAI,
|
||||
LENTILS, HUMMOUS, VINDALOO;
|
||||
LENTILS, HUMMUS, VINDALOO;
|
||||
}
|
||||
enum Dessert implements Food {
|
||||
TIRAMISU, GELATO, BLACK_FOREST_CAKE,
|
||||
|
@ -3,7 +3,7 @@
|
||||
// We make no guarantees that this code is fit for any purpose.
|
||||
// Visit http://OnJava8.com for more book information.
|
||||
import collections.MapOfList;
|
||||
import typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
public class IndividualTest {
|
||||
|
@ -3,7 +3,7 @@
|
||||
// We make no guarantees that this code is fit for any purpose.
|
||||
// Visit http://OnJava8.com for more book information.
|
||||
// Using Collection.checkedList()
|
||||
import typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.*;
|
||||
|
||||
public class CheckedList {
|
||||
@ -30,6 +30,6 @@ public class CheckedList {
|
||||
}
|
||||
/* Output:
|
||||
Expected: java.lang.ClassCastException: Attempt to
|
||||
insert class typeinfo.pets.Cat element into collection
|
||||
with element type class typeinfo.pets.Dog
|
||||
insert class reflection.pets.Cat element into collection
|
||||
with element type class reflection.pets.Dog
|
||||
*/
|
||||
|
@ -3,7 +3,7 @@
|
||||
// We make no guarantees that this code is fit for any purpose.
|
||||
// Visit http://OnJava8.com for more book information.
|
||||
// "Assisted Latent Typing"
|
||||
import typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
import java.util.function.*;
|
||||
|
||||
class PerformingDogA extends Dog {
|
||||
|
@ -3,7 +3,7 @@
|
||||
// We make no guarantees that this code is fit for any purpose.
|
||||
// Visit http://OnJava8.com for more book information.
|
||||
// No (direct) latent typing in Java
|
||||
import typeinfo.pets.*;
|
||||
import reflection.pets.*;
|
||||
|
||||
class PerformingDog extends Dog implements Performs {
|
||||
@Override
|
||||
|
@ -10,7 +10,7 @@ public class GenericHolder<T> {
|
||||
public T get() { return a; }
|
||||
public static void main(String[] args) {
|
||||
GenericHolder<Automobile> h3 =
|
||||
new GenericHolder<Automobile>();
|
||||
new GenericHolder<>();
|
||||
h3.set(new Automobile()); // type checked
|
||||
Automobile a = h3.get(); // No cast needed
|
||||
//- h3.set("Not an Automobile"); // Error
|
||||
|
@ -6,7 +6,7 @@ project(':validating') {
|
||||
|
||||
project(':equalshashcode') {
|
||||
dependencies {
|
||||
compile project(':typeinfo')
|
||||
compile project(':reflection')
|
||||
compile project(':collections')
|
||||
}
|
||||
}
|
||||
@ -48,13 +48,13 @@ project(':hiding') {
|
||||
|
||||
project(':generics') {
|
||||
dependencies {
|
||||
compile project(':typeinfo')
|
||||
compile project(':reflection')
|
||||
}
|
||||
}
|
||||
|
||||
project(':collections') {
|
||||
dependencies {
|
||||
compile project(':typeinfo')
|
||||
compile project(':reflection')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ public class Flower {
|
||||
}
|
||||
Flower() {
|
||||
this("hi", 47);
|
||||
System.out.println("no-arg constructor");
|
||||
System.out.println("Zero-argument constructor");
|
||||
}
|
||||
void printPetalCount() {
|
||||
//- this(11); // Not inside non-constructor!
|
||||
@ -41,6 +41,6 @@ public class Flower {
|
||||
/* Output:
|
||||
Constructor w/ int arg only, petalCount= 47
|
||||
String & int args
|
||||
no-arg constructor
|
||||
Zero-argument constructor
|
||||
petalCount = 47 s = hi
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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.
|
||||
// Overloading based on the order of the arguments
|
||||
// Overloading based on parameter order
|
||||
|
||||
public class OverloadingOrder {
|
||||
static void f(String s, int i) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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.
|
||||
// Constructors can have arguments
|
||||
// Constructors can have parameters
|
||||
|
||||
class Rock2 {
|
||||
Rock2(int i) {
|
||||
|
@ -2,6 +2,7 @@
|
||||
// (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.
|
||||
|
||||
/** You can <em>even</em> insert a list:
|
||||
* <ol>
|
||||
* <li> Item one
|
||||
@ -9,4 +10,5 @@
|
||||
* <li> Item three
|
||||
* </ol>
|
||||
*/
|
||||
|
||||
public class Documentation3 {}
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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.
|
||||
// Supplier from a class with a no-arg constructor
|
||||
// Supplier from a class with a zero-argument constructor
|
||||
package onjava;
|
||||
import java.util.function.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
@ -130,7 +130,7 @@ public class Countries {
|
||||
{"MOLDOVA","Chisinau"},
|
||||
{"RUSSIA","Moscow"},
|
||||
{"TAJIKISTAN","Dushanbe"},
|
||||
{"TURKMENISTAN","Ashkabad"},
|
||||
{"TURKMENISTAN","Ashkhabad"},
|
||||
{"UKRAINE","Kyiv"},
|
||||
{"UZBEKISTAN","Tashkent"},
|
||||
// Europe
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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.
|
||||
// Helper interface to allow lambda expressions
|
||||
// Helper interface to allow lambda expressions.
|
||||
package onjava;
|
||||
import java.awt.event.*;
|
||||
|
||||
|
@ -63,11 +63,11 @@ public class AtUnit implements ProcessFiles.Strategy {
|
||||
.getDeclaredConstructor()
|
||||
.getModifiers())) {
|
||||
System.out.println("Error: " + testClass +
|
||||
" no-arg constructor must be public");
|
||||
" zero-argument constructor must be public");
|
||||
System.exit(1);
|
||||
}
|
||||
} catch(NoSuchMethodException e) {
|
||||
// Synthesized no-arg constructor; OK
|
||||
// Synthesized zero-argument constructor; OK
|
||||
}
|
||||
System.out.println(testClass.getName());
|
||||
}
|
||||
@ -159,7 +159,7 @@ public class AtUnit implements ProcessFiles.Strategy {
|
||||
throw new RuntimeException("Couldn't run " +
|
||||
"@TestObject (creator) method.");
|
||||
}
|
||||
} else { // Use the no-arg constructor:
|
||||
} else { // Use the zero-argument constructor:
|
||||
try {
|
||||
return testClass
|
||||
.getConstructor().newInstance();
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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.
|
||||
// Demonstration of Observer pattern using
|
||||
// Demonstration of the Observer pattern using
|
||||
// Java's built-in observer classes.
|
||||
// {ExcludeFromGradle} // Won't work under WSL2
|
||||
import javax.swing.*;
|
||||
@ -12,46 +12,34 @@ import java.util.*;
|
||||
import onjava.*;
|
||||
import onjava.MouseClick;
|
||||
|
||||
// You must inherit a new type of Observable:
|
||||
@SuppressWarnings("deprecation")
|
||||
class BoxObservable extends Observable {
|
||||
class Boxes extends JFrame {
|
||||
Observable notifier = new Observable() {
|
||||
@Override
|
||||
public void notifyObservers(Object b) {
|
||||
// Otherwise it won't propagate changes:
|
||||
setChanged();
|
||||
super.notifyObservers(b);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class BoxObserver extends JFrame {
|
||||
Observable notifier = new BoxObservable();
|
||||
public BoxObserver(int grid) {
|
||||
};
|
||||
public Boxes(int grid) {
|
||||
setTitle("Demonstrates Observer pattern");
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(new GridLayout(grid, grid));
|
||||
for(int x = 0; x < grid; x++)
|
||||
for(int y = 0; y < grid; y++)
|
||||
cp.add(new OCBox(x, y, notifier));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
// For automated test runs:
|
||||
// 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);
|
||||
cp.add(new Box(x, y, notifier));
|
||||
setSize(500, 400);
|
||||
setVisible(true);
|
||||
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
class OCBox extends JPanel implements Observer {
|
||||
Observable notifier;
|
||||
int x, y; // Locations in grid
|
||||
Color cColor = newColor();
|
||||
class Box extends JPanel implements Observer {
|
||||
int x, y; // Location in grid
|
||||
Color color = COLORS[
|
||||
(int)(Math.random() * COLORS.length)
|
||||
];
|
||||
static final Color[] COLORS = {
|
||||
Color.black, Color.blue, Color.cyan,
|
||||
Color.darkGray, Color.gray, Color.green,
|
||||
@ -59,35 +47,38 @@ class OCBox extends JPanel implements Observer {
|
||||
Color.orange, Color.pink, Color.red,
|
||||
Color.white, Color.yellow
|
||||
};
|
||||
static Color newColor() {
|
||||
return COLORS[
|
||||
(int)(Math.random() * COLORS.length)
|
||||
];
|
||||
}
|
||||
OCBox(int x, int y, Observable notifier) {
|
||||
Box(int x, int y, Observable notifier) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
notifier.addObserver(this);
|
||||
this.notifier = notifier;
|
||||
addMouseListener((MouseClick)
|
||||
e -> notifier.notifyObservers(OCBox.this));
|
||||
e -> notifier.notifyObservers(Box.this));
|
||||
}
|
||||
@Override public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
g.setColor(cColor);
|
||||
g.setColor(color);
|
||||
Dimension s = getSize();
|
||||
g.fillRect(0, 0, s.width, s.height);
|
||||
}
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
OCBox clicked = (OCBox)arg;
|
||||
Box clicked = (Box)arg;
|
||||
if(nextTo(clicked)) {
|
||||
cColor = clicked.cColor;
|
||||
color = clicked.color;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
private boolean nextTo(OCBox b) {
|
||||
private boolean nextTo(Box b) {
|
||||
return Math.abs(x - b.x) <= 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);
|
||||
}
|
||||
}
|
||||
|
42
patterns/CleanTheFloor.java
Normal file
42
patterns/CleanTheFloor.java
Normal 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
|
||||
*/
|
@ -4,16 +4,23 @@
|
||||
// Visit http://OnJava8.com for more book information.
|
||||
import java.util.*;
|
||||
|
||||
class Command {
|
||||
public final String msg;
|
||||
public Command(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
|
||||
public class CommandPattern {
|
||||
public static void show(Command cmd) {
|
||||
System.out.println(cmd.msg);
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
List<Runnable> macro = Arrays.asList(
|
||||
() -> System.out.print("Hello "),
|
||||
() -> System.out.print("World! "),
|
||||
() -> System.out.print("I'm the command pattern!")
|
||||
);
|
||||
macro.forEach(Runnable::run);
|
||||
show(new Command("First Command"));
|
||||
show(new Command("Second Command"));
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
Hello World! I'm the command pattern!
|
||||
First Command
|
||||
Second Command
|
||||
*/
|
||||
|
25
patterns/Macro.java
Normal file
25
patterns/Macro.java
Normal 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!
|
||||
*/
|
@ -2,7 +2,7 @@
|
||||
// (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.
|
||||
// Demonstration of multiple dispatching
|
||||
// Demonstration of multiple dispatching.
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.util.stream.*;
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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.
|
||||
// Simple demonstration of the Proxy pattern
|
||||
// Basic demonstration of the Proxy pattern.
|
||||
|
||||
interface ProxyBase {
|
||||
void f();
|
||||
@ -11,10 +11,8 @@ interface ProxyBase {
|
||||
}
|
||||
|
||||
class Proxy implements ProxyBase {
|
||||
private ProxyBase implementation;
|
||||
Proxy() {
|
||||
implementation = new Implementation();
|
||||
}
|
||||
private ProxyBase implementation =
|
||||
new Implementation();
|
||||
// Pass method calls to the implementation:
|
||||
@Override
|
||||
public void f() { implementation.f(); }
|
||||
|
9
patterns/Resource.java
Normal file
9
patterns/Resource.java
Normal 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);
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
// (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.
|
||||
// A simple static factory method
|
||||
// A basic static factory method.
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
import patterns.shapes.*;
|
||||
|
@ -8,9 +8,9 @@ import java.util.stream.*;
|
||||
import patterns.shapes.*;
|
||||
|
||||
public class ShapeFactory2 implements FactoryMethod {
|
||||
Map<String, Constructor> factories =
|
||||
private Map<String, Constructor> factories =
|
||||
new HashMap<>();
|
||||
static Constructor load(String id) {
|
||||
private static Constructor load(String id) {
|
||||
System.out.println("loading " + id);
|
||||
try {
|
||||
return Class.forName("patterns.shapes." + id)
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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.
|
||||
// Polymorphic factory methods
|
||||
// Polymorphic factory methods.
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.util.stream.*;
|
||||
@ -19,14 +19,15 @@ class RandomShapes implements Supplier<Shape> {
|
||||
this.factories = factories;
|
||||
}
|
||||
@Override public Shape get() {
|
||||
return factories[
|
||||
rand.nextInt(factories.length)].create();
|
||||
return
|
||||
factories[rand.nextInt(factories.length)]
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
public class ShapeFactory3 {
|
||||
public static void main(String[] args) {
|
||||
RandomShapes rs = new RandomShapes(
|
||||
RandomShapes rs = new RandomShapes( // [1]
|
||||
Circle::new, Square::new, Triangle::new
|
||||
);
|
||||
Stream.generate(rs)
|
||||
|
18
patterns/Single.java
Normal file
18
patterns/Single.java
Normal 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; }
|
||||
}
|
@ -3,58 +3,45 @@
|
||||
// We make no guarantees that this code is fit for any purpose.
|
||||
// Visit http://OnJava8.com for more book information.
|
||||
|
||||
interface Resource {
|
||||
int getValue();
|
||||
void setValue(int x);
|
||||
final class IntegerSingleton
|
||||
implements Resource<Integer> {
|
||||
private static IntegerSingleton value =
|
||||
new IntegerSingleton();
|
||||
private Integer i = Integer.valueOf(0);
|
||||
private IntegerSingleton() {
|
||||
System.out.println("IntegerSingleton()");
|
||||
}
|
||||
|
||||
// This isn't inherited from a Cloneable
|
||||
// base class and cloneability isn't added so
|
||||
// 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 {
|
||||
private static Resource resource =
|
||||
new ResourceImpl(47);
|
||||
}
|
||||
public static Resource getResource() {
|
||||
return ResourceHolder.resource;
|
||||
public static IntegerSingleton instance() {
|
||||
return value;
|
||||
}
|
||||
@Override public synchronized
|
||||
Integer get() { return i; }
|
||||
@Override public synchronized
|
||||
void set(Integer x) { i = x; }
|
||||
}
|
||||
|
||||
public class SingletonPattern {
|
||||
public static void main(String[] args) {
|
||||
Resource r = Singleton.getResource();
|
||||
System.out.println(r.getValue());
|
||||
Resource s2 = Singleton.getResource();
|
||||
s2.setValue(9);
|
||||
System.out.println(r.getValue());
|
||||
try {
|
||||
// Can't do this: compile-time error.
|
||||
// Singleton s3 = (Singleton)s2.clone();
|
||||
} catch(Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
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) {
|
||||
System.out.println("Inside main()");
|
||||
Resource<Integer> ir =
|
||||
IntegerSingleton.instance();
|
||||
Resource<Integer> ir2 =
|
||||
IntegerSingleton.instance();
|
||||
show(ir);
|
||||
put(ir2, Integer.valueOf(9));
|
||||
show(ir);
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
47
|
||||
Inside main()
|
||||
IntegerSingleton()
|
||||
0
|
||||
9
|
||||
*/
|
||||
|
16
patterns/SingletonPattern2.java
Normal file
16
patterns/SingletonPattern2.java
Normal 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
|
||||
*/
|
33
patterns/SingletonPattern3.java
Normal file
33
patterns/SingletonPattern3.java
Normal 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!
|
||||
*/
|
@ -2,34 +2,24 @@
|
||||
// (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.
|
||||
// Simple demonstration of the State pattern
|
||||
// Basic demonstration of the State pattern.
|
||||
|
||||
interface StateBase {
|
||||
void f();
|
||||
void g();
|
||||
void h();
|
||||
void changeImp(StateBase newImp);
|
||||
}
|
||||
|
||||
class State implements StateBase {
|
||||
private StateBase implementation;
|
||||
State(StateBase imp) {
|
||||
class State {
|
||||
private State implementation;
|
||||
protected State() {}
|
||||
public State(State imp) {
|
||||
implementation = imp;
|
||||
}
|
||||
@Override
|
||||
public void changeImp(StateBase newImp) {
|
||||
public void change(State newImp) {
|
||||
implementation = newImp;
|
||||
}
|
||||
// Pass method calls to the implementation:
|
||||
@Override
|
||||
// Forward method calls to the implementation:
|
||||
public void f() { implementation.f(); }
|
||||
@Override
|
||||
public void g() { implementation.g(); }
|
||||
@Override
|
||||
public void h() { implementation.h(); }
|
||||
}
|
||||
|
||||
class Implementation1 implements StateBase {
|
||||
class Implementation1 extends State {
|
||||
@Override public void f() {
|
||||
System.out.println("Implementation1.f()");
|
||||
}
|
||||
@ -39,11 +29,9 @@ class Implementation1 implements StateBase {
|
||||
@Override public void h() {
|
||||
System.out.println("Implementation1.h()");
|
||||
}
|
||||
@Override
|
||||
public void changeImp(StateBase newImp) {}
|
||||
}
|
||||
|
||||
class Implementation2 implements StateBase {
|
||||
class Implementation2 extends State {
|
||||
@Override public void f() {
|
||||
System.out.println("Implementation2.f()");
|
||||
}
|
||||
@ -53,28 +41,27 @@ class Implementation2 implements StateBase {
|
||||
@Override public void h() {
|
||||
System.out.println("Implementation2.h()");
|
||||
}
|
||||
@Override
|
||||
public void changeImp(StateBase newImp) {}
|
||||
}
|
||||
|
||||
public class StateDemo {
|
||||
static void test(StateBase b) {
|
||||
b.f();
|
||||
b.g();
|
||||
b.h();
|
||||
static void test(State s) {
|
||||
s.f();
|
||||
s.g();
|
||||
s.h();
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
StateBase b =
|
||||
new State(new Implementation1());
|
||||
test(b);
|
||||
b.changeImp(new Implementation2());
|
||||
test(b);
|
||||
State s = new State(new Implementation1());
|
||||
test(s);
|
||||
System.out.println("Changing implementation");
|
||||
s.change(new Implementation2());
|
||||
test(s);
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
Implementation1.f()
|
||||
Implementation1.g()
|
||||
Implementation1.h()
|
||||
Changing implementation
|
||||
Implementation2.f()
|
||||
Implementation2.g()
|
||||
Implementation2.h()
|
||||
|
@ -2,29 +2,29 @@
|
||||
// (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.
|
||||
// Simple demonstration of Template Method
|
||||
// Basic Template Method pattern.
|
||||
import java.util.stream.*;
|
||||
|
||||
abstract class ApplicationFramework {
|
||||
ApplicationFramework() {
|
||||
templateMethod();
|
||||
}
|
||||
abstract void customize1();
|
||||
abstract void customize2();
|
||||
abstract void customize1(int n);
|
||||
abstract void customize2(int n);
|
||||
// "private" means automatically "final":
|
||||
private void templateMethod() {
|
||||
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 {
|
||||
@Override void customize1() {
|
||||
System.out.print("Hello ");
|
||||
@Override void customize1(int n) {
|
||||
System.out.print("customize1 " + n);
|
||||
}
|
||||
@Override void customize2() {
|
||||
System.out.println("World!");
|
||||
@Override void customize2(int n) {
|
||||
System.out.println(" customize2 " + n);
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,9 +34,9 @@ public class TemplateMethod {
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
Hello World!
|
||||
Hello World!
|
||||
Hello World!
|
||||
Hello World!
|
||||
Hello World!
|
||||
customize1 0 customize2 0
|
||||
customize1 1 customize2 1
|
||||
customize1 2 customize2 2
|
||||
customize1 3 customize2 3
|
||||
customize1 4 customize2 4
|
||||
*/
|
||||
|
20
patterns/TestSingle.java
Normal file
20
patterns/TestSingle.java
Normal 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
21
patterns/TypeMap.java
Normal 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();
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
// (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 example of the Abstract Factory pattern
|
||||
// An example of the Abstract Factory pattern.
|
||||
// {java patterns.abstractfactory.GameEnvironment}
|
||||
package patterns.abstractfactory;
|
||||
import java.util.function.*;
|
||||
@ -23,10 +23,10 @@ class Kitty implements Player {
|
||||
}
|
||||
}
|
||||
|
||||
class KungFuGuy implements Player {
|
||||
class Fighter implements Player {
|
||||
@Override
|
||||
public void interactWith(Obstacle ob) {
|
||||
System.out.print("KungFuGuy now battles a ");
|
||||
System.out.print("Fighter now battles a ");
|
||||
ob.action();
|
||||
}
|
||||
}
|
||||
@ -37,9 +37,9 @@ class Puzzle implements Obstacle {
|
||||
}
|
||||
}
|
||||
|
||||
class NastyWeapon implements Obstacle {
|
||||
class Weapon implements Obstacle {
|
||||
@Override public void action() {
|
||||
System.out.println("NastyWeapon");
|
||||
System.out.println("Weapon");
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,11 +58,11 @@ extends GameElementFactory {
|
||||
}
|
||||
}
|
||||
|
||||
class KillAndDismember
|
||||
class Melee
|
||||
extends GameElementFactory {
|
||||
KillAndDismember() {
|
||||
player = KungFuGuy::new;
|
||||
obstacle = NastyWeapon::new;
|
||||
Melee() {
|
||||
player = Fighter::new;
|
||||
obstacle = Weapon::new;
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,15 +80,15 @@ public class GameEnvironment {
|
||||
public static void main(String[] args) {
|
||||
GameElementFactory
|
||||
kp = new KittiesAndPuzzles(),
|
||||
kd = new KillAndDismember();
|
||||
ml = new Melee();
|
||||
GameEnvironment
|
||||
g1 = new GameEnvironment(kp),
|
||||
g2 = new GameEnvironment(kd);
|
||||
g2 = new GameEnvironment(ml);
|
||||
g1.play();
|
||||
g2.play();
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
Kitty has encountered a Puzzle
|
||||
KungFuGuy now battles a NastyWeapon
|
||||
Fighter now battles a Weapon
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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.
|
||||
// Variations on the Adapter pattern
|
||||
// Variations on the Adapter pattern.
|
||||
// {java patterns.adapt.Adapter}
|
||||
package patterns.adapt;
|
||||
|
||||
|
@ -2,55 +2,32 @@
|
||||
// (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 the Functional interface
|
||||
// {java patterns.chain.ChainOfResponsibility}
|
||||
package patterns.chain;
|
||||
import java.util.*;
|
||||
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 {
|
||||
Result algorithm(List<Double> line);
|
||||
}
|
||||
|
||||
class FindMinima {
|
||||
public static Result leastSquares(List<Double> line) {
|
||||
System.out.println("LeastSquares.algorithm");
|
||||
boolean weSucceed = false;
|
||||
if(weSucceed) // Actual test/calculation here
|
||||
return new Result(Arrays.asList(1.1, 2.2));
|
||||
public static Result test(
|
||||
boolean success, String id, double d1, double d2) {
|
||||
System.out.println(id);
|
||||
if(success) // Actual test/calculation here
|
||||
return new Result(Arrays.asList(d1, d2));
|
||||
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) {
|
||||
System.out.println("Perturbation.algorithm");
|
||||
boolean weSucceed = false;
|
||||
if(weSucceed) // Actual test/calculation here
|
||||
return new Result(Arrays.asList(3.3, 4.4));
|
||||
else
|
||||
return new Fail();
|
||||
return test(false, "Perturbation", 3.3, 4.4);
|
||||
}
|
||||
public static Result bisection(List<Double> line) {
|
||||
System.out.println("Bisection.algorithm");
|
||||
boolean weSucceed = true;
|
||||
if(weSucceed) // Actual test/calculation here
|
||||
return new Result(Arrays.asList(5.5, 6.6));
|
||||
else
|
||||
return new Fail();
|
||||
return test(true, "Bisection", 5.5, 6.6);
|
||||
}
|
||||
static List<Function<List<Double>, Result>>
|
||||
algorithms = Arrays.asList(
|
||||
@ -65,7 +42,7 @@ class FindMinima {
|
||||
if(result.success)
|
||||
return result;
|
||||
}
|
||||
return new Fail();
|
||||
return Result.fail;
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,8 +60,8 @@ public class ChainOfResponsibility {
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
LeastSquares.algorithm
|
||||
Perturbation.algorithm
|
||||
Bisection.algorithm
|
||||
LeastSquares
|
||||
Perturbation
|
||||
Bisection
|
||||
[5.5, 6.6]
|
||||
*/
|
||||
|
21
patterns/chain/Result.java
Normal file
21
patterns/chain/Result.java
Normal 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();
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
// (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 double dispatching
|
||||
// Aluminum with double dispatching.
|
||||
package patterns.doubledispatch;
|
||||
import patterns.trash.*;
|
||||
import java.util.*;
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 double dispatching
|
||||
// Cardboard with double dispatching.
|
||||
package patterns.doubledispatch;
|
||||
import patterns.trash.*;
|
||||
import java.util.*;
|
||||
|
@ -3,90 +3,104 @@
|
||||
// We make no guarantees that this code is fit for any purpose.
|
||||
// Visit http://OnJava8.com for more book information.
|
||||
// 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}
|
||||
package patterns.doubledispatch;
|
||||
import patterns.trash.*;
|
||||
import java.util.*;
|
||||
|
||||
class AluminumBin extends TypedBin {
|
||||
public AluminumBin() { super("Aluminum"); }
|
||||
@Override public boolean add(Aluminum a) {
|
||||
return addIt(a);
|
||||
}
|
||||
}
|
||||
|
||||
class PaperBin extends TypedBin {
|
||||
public PaperBin() { super("Paper"); }
|
||||
@Override public boolean add(Paper a) {
|
||||
return addIt(a);
|
||||
}
|
||||
}
|
||||
|
||||
class GlassBin extends TypedBin {
|
||||
public GlassBin() { super("Glass"); }
|
||||
@Override public boolean add(Glass a) {
|
||||
return addIt(a);
|
||||
}
|
||||
}
|
||||
|
||||
class CardboardBin extends TypedBin {
|
||||
public CardboardBin() { super("Cardboard"); }
|
||||
@Override public boolean add(Cardboard a) {
|
||||
return addIt(a);
|
||||
}
|
||||
}
|
||||
|
||||
class TrashBinSet {
|
||||
private List<TypedBin> binSet = Arrays.asList(
|
||||
new AluminumBin(),
|
||||
new PaperBin(),
|
||||
new GlassBin(),
|
||||
new CardboardBin()
|
||||
public final List<TypedBin> binSet =
|
||||
Arrays.asList(
|
||||
new AluminumBin(), new PaperBin(),
|
||||
new GlassBin(), new CardboardBin()
|
||||
);
|
||||
@SuppressWarnings("unchecked")
|
||||
public void sortIntoBins(List bin) {
|
||||
bin.forEach( aBin -> {
|
||||
TypedBinMember t = (TypedBinMember)aBin;
|
||||
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 static void main(String[] args) {
|
||||
List<Trash> bin = new ArrayList<>();
|
||||
TrashBinSet bins = new TrashBinSet();
|
||||
// ParseTrash still works, without changes:
|
||||
ParseTrash.fillBin("doubledispatch", bin);
|
||||
TrashBinSet bins = new TrashBinSet();
|
||||
// Sort from the master bin into the
|
||||
// individually-typed bins:
|
||||
bins.sortIntoBins(bin);
|
||||
// Perform sumValue for each bin...
|
||||
bins.binSet()
|
||||
.forEach(tb -> Trash.sumValue(tb.v));
|
||||
// ... and for the master bin
|
||||
Trash.sumValue(bin);
|
||||
// Sum value of each bin...
|
||||
bins.binSet.forEach(tb ->
|
||||
TrashValue.sum(tb.bin(), tb.type));
|
||||
// ... and for the master bin:
|
||||
TrashValue.sum(bin, "Trash");
|
||||
}
|
||||
}
|
||||
/* Output: (First and Last 10 Lines)
|
||||
Loading patterns.doubledispatch.Glass
|
||||
/* Output:
|
||||
Loading patterns.doubledispatch.Cardboard
|
||||
Loading patterns.doubledispatch.Paper
|
||||
Loading patterns.doubledispatch.Aluminum
|
||||
Loading patterns.doubledispatch.Cardboard
|
||||
weight of patterns.doubledispatch.Aluminum = 89.0
|
||||
weight of patterns.doubledispatch.Aluminum = 76.0
|
||||
weight of patterns.doubledispatch.Aluminum = 25.0
|
||||
weight of patterns.doubledispatch.Aluminum = 34.0
|
||||
weight of patterns.doubledispatch.Aluminum = 27.0
|
||||
weight of patterns.doubledispatch.Aluminum = 18.0
|
||||
...________...________...________...________...
|
||||
weight of patterns.doubledispatch.Aluminum = 93.0
|
||||
weight of patterns.doubledispatch.Glass = 93.0
|
||||
weight of patterns.doubledispatch.Paper = 80.0
|
||||
weight of patterns.doubledispatch.Glass = 36.0
|
||||
weight of patterns.doubledispatch.Glass = 12.0
|
||||
weight of patterns.doubledispatch.Glass = 60.0
|
||||
weight of patterns.doubledispatch.Paper = 66.0
|
||||
weight of patterns.doubledispatch.Aluminum = 36.0
|
||||
weight of patterns.doubledispatch.Cardboard = 22.0
|
||||
Total value = 1086.0599818825722
|
||||
Loading patterns.doubledispatch.Glass
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 double dispatching
|
||||
// Glass with double dispatching.
|
||||
package patterns.doubledispatch;
|
||||
import patterns.trash.*;
|
||||
import java.util.*;
|
||||
|
@ -2,7 +2,7 @@
|
||||
// (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 double dispatching
|
||||
// Paper with double dispatching.
|
||||
package patterns.doubledispatch;
|
||||
import patterns.trash.*;
|
||||
import java.util.*;
|
||||
|
@ -2,15 +2,24 @@
|
||||
// (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.
|
||||
// A List that can grab the right type
|
||||
// A List that can grab the right type.
|
||||
package patterns.doubledispatch;
|
||||
import patterns.trash.*;
|
||||
import java.util.*;
|
||||
|
||||
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) {
|
||||
v.add(t);
|
||||
typedBin.add(t);
|
||||
return true;
|
||||
}
|
||||
public boolean add(Aluminum a) {
|
||||
|
@ -2,13 +2,12 @@
|
||||
// (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 for adding the double dispatching
|
||||
// method to the trash hierarchy without
|
||||
// modifying the original hierarchy
|
||||
// Adapts the double-dispatching
|
||||
// method into the trash hierarchy without
|
||||
// modifying the original hierarchy.
|
||||
package patterns.doubledispatch;
|
||||
import java.util.*;
|
||||
|
||||
public interface TypedBinMember {
|
||||
// The new method:
|
||||
boolean addToBin(List<TypedBin> bins);
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
@ -2,19 +2,35 @@
|
||||
// (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.
|
||||
// Demonstration of "Observer" pattern
|
||||
// Demonstration of the Observer pattern.
|
||||
// {java patterns.observer.ObservedFlower}
|
||||
package patterns.observer;
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
class Flower {
|
||||
private boolean isOpen;
|
||||
private boolean alreadyOpen;
|
||||
private boolean alreadyClosed;
|
||||
Flower() { isOpen = false; }
|
||||
OpenNotifier opening = new OpenNotifier();
|
||||
CloseNotifier closing = new CloseNotifier();
|
||||
private boolean isOpen = false;
|
||||
private boolean alreadyOpen = false;
|
||||
private boolean alreadyClosed = false;
|
||||
Observable opening = new Observable() {
|
||||
@Override public void notifyObservers() {
|
||||
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
|
||||
isOpen = true;
|
||||
opening.notifyObservers();
|
||||
@ -25,55 +41,32 @@ class Flower {
|
||||
closing.notifyObservers();
|
||||
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")
|
||||
class Bee {
|
||||
private String name;
|
||||
Bee(String nm) { name = nm; }
|
||||
private String id;
|
||||
Bee(String name) { id = name; }
|
||||
// Observe openings:
|
||||
public Observer openObserver() {
|
||||
return (ob, a) -> System.out.println(
|
||||
"Bee " + name + "'s breakfast time!");
|
||||
}
|
||||
public final Observer whenOpened = (ob, a) ->
|
||||
System.out.println(
|
||||
"Bee " + id + "'s breakfast time!");
|
||||
// Observe closings:
|
||||
public Observer closeObserver() {
|
||||
return (ob, a) -> System.out.println(
|
||||
"Bee " + name + "'s bed time!");
|
||||
}
|
||||
public final Observer whenClosed = (ob, a) ->
|
||||
System.out.println(
|
||||
"Bee " + id + "'s bed time!");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
class Hummingbird {
|
||||
private String name;
|
||||
Hummingbird(String nm) { name = nm; }
|
||||
public Observer openObserver() {
|
||||
return (ob, a) -> System.out.println(
|
||||
"Hummingbird " + name +
|
||||
"'s breakfast time!");
|
||||
}
|
||||
public Observer closeObserver() {
|
||||
return (ob, a) -> System.out.println(
|
||||
"Hummingbird " + name + "'s bed time!");
|
||||
}
|
||||
private String id;
|
||||
Hummingbird(String name) { id = name; }
|
||||
public final Observer whenOpened = (ob, a) ->
|
||||
System.out.println("Hummingbird " +
|
||||
id + "'s breakfast time!");
|
||||
public final Observer whenClosed = (ob, a) ->
|
||||
System.out.println("Hummingbird " +
|
||||
id + "'s bed time!");
|
||||
}
|
||||
|
||||
public class ObservedFlower {
|
||||
@ -85,39 +78,46 @@ public class ObservedFlower {
|
||||
Hummingbird
|
||||
ha = new Hummingbird("A"),
|
||||
hb = new Hummingbird("B");
|
||||
f.opening.addObserver(ha.openObserver());
|
||||
f.opening.addObserver(hb.openObserver());
|
||||
f.opening.addObserver(ba.openObserver());
|
||||
f.opening.addObserver(bb.openObserver());
|
||||
f.closing.addObserver(ha.closeObserver());
|
||||
f.closing.addObserver(hb.closeObserver());
|
||||
f.closing.addObserver(ba.closeObserver());
|
||||
f.closing.addObserver(bb.closeObserver());
|
||||
// Hummingbird B decides to sleep in:
|
||||
f.opening.deleteObserver(hb.openObserver());
|
||||
f.opening.addObserver(ha.whenOpened);
|
||||
f.opening.addObserver(hb.whenOpened);
|
||||
f.opening.addObserver(ba.whenOpened);
|
||||
f.opening.addObserver(bb.whenOpened);
|
||||
f.closing.addObserver(ha.whenClosed);
|
||||
f.closing.addObserver(hb.whenClosed);
|
||||
f.closing.addObserver(ba.whenClosed);
|
||||
f.closing.addObserver(bb.whenClosed);
|
||||
// Hummingbird B decides to sleep in.
|
||||
// Removing whenOpened stops open updates.
|
||||
f.opening.deleteObserver(hb.whenOpened);
|
||||
// A change that interests observers:
|
||||
f.open();
|
||||
f.open(); // It's already open, no change.
|
||||
// Bee A doesn't want to go to bed:
|
||||
f.closing.deleteObserver(ba.closeObserver());
|
||||
f.open(); // No effect: it's already open.
|
||||
System.out.println("---------------");
|
||||
// Bee A doesn't want to go to bed.
|
||||
// Removing whenClosed stops close updates.
|
||||
f.closing.deleteObserver(ba.whenClosed);
|
||||
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.open();
|
||||
f.close();
|
||||
f.open(); // No observers to update.
|
||||
System.out.println("###############");
|
||||
f.close(); // Close observers are still there.
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
Bee B's breakfast time!
|
||||
Bee A's breakfast time!
|
||||
Hummingbird B's breakfast time!
|
||||
Hummingbird A's breakfast time!
|
||||
---------------
|
||||
Bee B's bed time!
|
||||
Bee A's bed time!
|
||||
Hummingbird B's bed time!
|
||||
Hummingbird A's bed time!
|
||||
+++++++++++++++
|
||||
===============
|
||||
###############
|
||||
Bee B's bed time!
|
||||
Bee A's bed time!
|
||||
Hummingbird B's bed time!
|
||||
Hummingbird A's bed time!
|
||||
*/
|
||||
|
@ -2,72 +2,25 @@
|
||||
// (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.
|
||||
// Recycling with RTTI
|
||||
// Recycling with reflection.
|
||||
// {java patterns.recyclea.RecycleA}
|
||||
package patterns.recyclea;
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.util.stream.*;
|
||||
import patterns.trash.*;
|
||||
|
||||
abstract class Trash {
|
||||
double weight;
|
||||
Trash(double wt) { weight = wt; }
|
||||
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 =
|
||||
class SimpleFactory {
|
||||
static final
|
||||
List<Function<Double, Trash>> constructors =
|
||||
Arrays.asList(
|
||||
Aluminum::new, Paper::new, Glass::new);
|
||||
static final int SZ = ttypes.size();
|
||||
static final int SIZE = constructors.size();
|
||||
private static SplittableRandom rand =
|
||||
new SplittableRandom(47);
|
||||
public static Trash newTrash() {
|
||||
return ttypes
|
||||
.get(rand.nextInt(SZ))
|
||||
new SplittableRandom(42);
|
||||
public static Trash random() {
|
||||
return constructors
|
||||
.get(rand.nextInt(SIZE))
|
||||
.apply(rand.nextDouble());
|
||||
}
|
||||
}
|
||||
@ -75,50 +28,37 @@ class TrashFactory {
|
||||
public class RecycleA {
|
||||
public static void main(String[] args) {
|
||||
List<Trash> bin =
|
||||
Stream.generate(TrashFactory::newTrash)
|
||||
.limit(25)
|
||||
Stream.generate(SimpleFactory::random)
|
||||
.limit(10)
|
||||
.collect(Collectors.toList());
|
||||
List<Glass> glassBin = new ArrayList<>();
|
||||
List<Paper> paperBin = new ArrayList<>();
|
||||
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);
|
||||
Bins bins = new Bins(bin);
|
||||
bins.show();
|
||||
}
|
||||
}
|
||||
/* Output: (First and Last 11 Lines)
|
||||
weight of Aluminum = 0.2893030122276371
|
||||
weight of Aluminum = 0.1970234961398979
|
||||
weight of Aluminum = 0.36295525806274787
|
||||
weight of Aluminum = 0.4825532324565849
|
||||
weight of Aluminum = 0.8036398273294586
|
||||
weight of Aluminum = 0.510430896154935
|
||||
weight of Aluminum = 0.6703377164093444
|
||||
weight of Aluminum = 0.41477933066243455
|
||||
weight of Aluminum = 0.3603022312124007
|
||||
weight of Aluminum = 0.43690089841661006
|
||||
weight of Aluminum = 0.6708820087907101
|
||||
...________...________...________...________...
|
||||
weight of Aluminum = 0.41477933066243455
|
||||
weight of Aluminum = 0.3603022312124007
|
||||
weight of Aluminum = 0.43690089841661006
|
||||
weight of Glass = 0.5999637765664924
|
||||
weight of Glass = 0.7748836191212746
|
||||
weight of Paper = 0.5735994548427199
|
||||
weight of Glass = 0.5362827750851034
|
||||
weight of Aluminum = 0.6708820087907101
|
||||
weight of Paper = 0.8370669795210507
|
||||
weight of Glass = 0.3397919679731668
|
||||
Total value = 9.90671597531968
|
||||
/* Output:
|
||||
Aluminum weight: 0.34 * price: 1.67 = 0.57
|
||||
Aluminum weight: 0.62 * price: 1.67 = 1.03
|
||||
Aluminum weight: 0.49 * price: 1.67 = 0.82
|
||||
Aluminum weight: 0.50 * price: 1.67 = 0.83
|
||||
Total Aluminum value = 3.26
|
||||
Paper weight: 0.69 * price: 0.10 = 0.07
|
||||
Total Paper value = 0.07
|
||||
Glass weight: 0.16 * price: 0.23 = 0.04
|
||||
Glass weight: 0.87 * price: 0.23 = 0.20
|
||||
Glass weight: 0.80 * price: 0.23 = 0.18
|
||||
Glass weight: 0.52 * price: 0.23 = 0.12
|
||||
Glass weight: 0.20 * price: 0.23 = 0.05
|
||||
Total Glass value = 0.59
|
||||
Total Cardboard value = 0.00
|
||||
Glass weight: 0.16 * price: 0.23 = 0.04
|
||||
Aluminum weight: 0.34 * price: 1.67 = 0.57
|
||||
Glass weight: 0.87 * price: 0.23 = 0.20
|
||||
Glass weight: 0.80 * price: 0.23 = 0.18
|
||||
Aluminum weight: 0.62 * price: 1.67 = 1.03
|
||||
Aluminum weight: 0.49 * price: 1.67 = 0.82
|
||||
Glass weight: 0.52 * price: 0.23 = 0.12
|
||||
Glass weight: 0.20 * price: 0.23 = 0.05
|
||||
Aluminum weight: 0.50 * price: 1.67 = 0.83
|
||||
Paper weight: 0.69 * price: 0.10 = 0.07
|
||||
Total Trash value = 3.91
|
||||
*/
|
||||
|
@ -10,47 +10,43 @@ import java.util.*;
|
||||
public class RecycleB {
|
||||
public static void main(String[] args) {
|
||||
List<Trash> bin = new ArrayList<>();
|
||||
// Fill up the Trash bin:
|
||||
ParseTrash.fillBin("trash", bin);
|
||||
List<Glass> glassBin = new ArrayList<>();
|
||||
List<Paper> paperBin = new ArrayList<>();
|
||||
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);
|
||||
Bins bins = new Bins(bin);
|
||||
bins.show();
|
||||
}
|
||||
}
|
||||
/* Output: (First and Last 10 Lines)
|
||||
Loading patterns.trash.Glass
|
||||
/* Output:
|
||||
Loading patterns.trash.Cardboard
|
||||
Loading patterns.trash.Paper
|
||||
Loading patterns.trash.Aluminum
|
||||
Loading patterns.trash.Cardboard
|
||||
weight of patterns.trash.Aluminum = 89.0
|
||||
weight of patterns.trash.Aluminum = 76.0
|
||||
weight of patterns.trash.Aluminum = 25.0
|
||||
weight of patterns.trash.Aluminum = 34.0
|
||||
weight of patterns.trash.Aluminum = 27.0
|
||||
weight of patterns.trash.Aluminum = 18.0
|
||||
...________...________...________...________...
|
||||
weight of patterns.trash.Aluminum = 93.0
|
||||
weight of patterns.trash.Glass = 93.0
|
||||
weight of patterns.trash.Paper = 80.0
|
||||
weight of patterns.trash.Glass = 36.0
|
||||
weight of patterns.trash.Glass = 12.0
|
||||
weight of patterns.trash.Glass = 60.0
|
||||
weight of patterns.trash.Paper = 66.0
|
||||
weight of patterns.trash.Aluminum = 36.0
|
||||
weight of patterns.trash.Cardboard = 22.0
|
||||
Total value = 1086.0599818825722
|
||||
Loading patterns.trash.Glass
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
*/
|
||||
|
@ -2,83 +2,105 @@
|
||||
// (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.
|
||||
// Adding more objects to the recycling problem
|
||||
// {java patterns.recyclec.RecycleC}
|
||||
package patterns.recyclec;
|
||||
import patterns.trash.*;
|
||||
import java.util.*;
|
||||
|
||||
// A List that admits only the right type:
|
||||
class Tbin<T extends Trash> extends ArrayList<T> {
|
||||
Class<T> binType;
|
||||
Tbin(Class<T> type) {
|
||||
binType = type;
|
||||
// A List that only admits the right type:
|
||||
class
|
||||
TrashBin<T extends Trash> extends ArrayList<T> {
|
||||
final Class<T> binType;
|
||||
TrashBin(Class<T> binType) {
|
||||
this.binType = binType;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
boolean grab(Trash t) {
|
||||
// Comparing class types:
|
||||
// Compare class types:
|
||||
if(t.getClass().equals(binType)) {
|
||||
add((T)t); // Downcast to this TBin's type
|
||||
return true; // Object grabbed
|
||||
add((T)t); // Downcast to this TrashBin type
|
||||
return true; // Trash grabbed
|
||||
}
|
||||
return false; // Object not grabbed
|
||||
return false; // Trash not grabbed
|
||||
}
|
||||
}
|
||||
|
||||
class TbinList<T extends Trash>
|
||||
extends ArrayList<Tbin<? extends T>> { // [1]
|
||||
boolean sort(T t) {
|
||||
for(Tbin<? extends T> ts : this)
|
||||
class TrashBinList<T extends Trash>
|
||||
extends ArrayList<TrashBin<? extends T>> { // [1]
|
||||
@SuppressWarnings("unchecked")
|
||||
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))
|
||||
return true;
|
||||
return false; // bin not found for t
|
||||
return false; // TrashBin not found for t
|
||||
}
|
||||
public void sortBin(TrashBin<T> bin) { // [2]
|
||||
for(T trash : bin)
|
||||
if(!sort(trash))
|
||||
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);
|
||||
}
|
||||
void sortBin(Tbin<T> bin) { // [2]
|
||||
for(T aBin : bin)
|
||||
if(!sort(aBin))
|
||||
System.err.println("Bin not found");
|
||||
}
|
||||
}
|
||||
|
||||
public class RecycleC {
|
||||
static Tbin<Trash> bin = new Tbin<>(Trash.class);
|
||||
public static void main(String[] args) {
|
||||
// Fill up the Trash bin:
|
||||
TrashBin<Trash> bin =
|
||||
new TrashBin<>(Trash.class);
|
||||
ParseTrash.fillBin("trash", bin);
|
||||
|
||||
TbinList<Trash> trashBins = new TbinList<>();
|
||||
trashBins.add(new Tbin<>(Aluminum.class));
|
||||
trashBins.add(new Tbin<>(Paper.class));
|
||||
trashBins.add(new Tbin<>(Glass.class));
|
||||
// add one line here: // [3]
|
||||
trashBins.add(new Tbin<>(Cardboard.class));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
TrashBinList<Trash> trashBins =
|
||||
new TrashBinList<>(
|
||||
Aluminum.class, Paper.class, Glass.class,
|
||||
// Add one item:
|
||||
Cardboard.class // [3]
|
||||
);
|
||||
trashBins.sortBin(bin); // [4]
|
||||
|
||||
trashBins.forEach(Trash::sumValue);
|
||||
Trash.sumValue(bin);
|
||||
trashBins.show();
|
||||
TrashValue.sum(bin, "Trash");
|
||||
}
|
||||
}
|
||||
/* Output: (First and Last 10 Lines)
|
||||
Loading patterns.trash.Glass
|
||||
/* Output:
|
||||
Loading patterns.trash.Cardboard
|
||||
Loading patterns.trash.Paper
|
||||
Loading patterns.trash.Aluminum
|
||||
Loading patterns.trash.Cardboard
|
||||
weight of patterns.trash.Aluminum = 89.0
|
||||
weight of patterns.trash.Aluminum = 76.0
|
||||
weight of patterns.trash.Aluminum = 25.0
|
||||
weight of patterns.trash.Aluminum = 34.0
|
||||
weight of patterns.trash.Aluminum = 27.0
|
||||
weight of patterns.trash.Aluminum = 18.0
|
||||
...________...________...________...________...
|
||||
weight of patterns.trash.Aluminum = 93.0
|
||||
weight of patterns.trash.Glass = 93.0
|
||||
weight of patterns.trash.Paper = 80.0
|
||||
weight of patterns.trash.Glass = 36.0
|
||||
weight of patterns.trash.Glass = 12.0
|
||||
weight of patterns.trash.Glass = 60.0
|
||||
weight of patterns.trash.Paper = 66.0
|
||||
weight of patterns.trash.Aluminum = 36.0
|
||||
weight of patterns.trash.Cardboard = 22.0
|
||||
Total value = 1086.0599818825722
|
||||
Loading patterns.trash.Glass
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
*/
|
||||
|
@ -2,9 +2,10 @@
|
||||
// (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 StateMachine pattern and Template method
|
||||
// The State Machine pattern.
|
||||
// {java patterns.state.StateMachineDemo}
|
||||
package patterns.state;
|
||||
import java.util.*;
|
||||
import onjava.Nap;
|
||||
|
||||
interface State {
|
||||
@ -16,7 +17,7 @@ abstract class StateMachine {
|
||||
protected abstract boolean changeState();
|
||||
// Template method:
|
||||
protected final void runAll() {
|
||||
while(changeState()) // Customizable
|
||||
while(changeState())
|
||||
currentState.run();
|
||||
}
|
||||
}
|
||||
@ -46,20 +47,19 @@ class Rinse implements State {
|
||||
|
||||
class Washer extends StateMachine {
|
||||
private int i = 0;
|
||||
// The state table:
|
||||
private State[] states = {
|
||||
private Iterator<State> states =
|
||||
Arrays.asList(
|
||||
new Wash(), new Spin(),
|
||||
new Rinse(), new Spin(),
|
||||
};
|
||||
new Rinse(), new Spin()
|
||||
).iterator();
|
||||
Washer() { runAll(); }
|
||||
@Override public boolean changeState() {
|
||||
if(i < states.length) {
|
||||
// Change the state by setting the
|
||||
// surrogate reference to a new object:
|
||||
currentState = states[i++];
|
||||
return true;
|
||||
} else
|
||||
if(!states.hasNext())
|
||||
return false;
|
||||
// Set the surrogate reference
|
||||
// to a new State object:
|
||||
currentState = states.next();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,13 +9,14 @@ import java.util.*;
|
||||
|
||||
// The common strategy base type:
|
||||
class FindMinima {
|
||||
protected
|
||||
Function<List<Double>, List<Double>> algorithm;
|
||||
}
|
||||
|
||||
// The various strategies:
|
||||
// The various strategies, each producing dummy data:
|
||||
class LeastSquares extends FindMinima {
|
||||
LeastSquares() {
|
||||
// Line is a sequence of points (Dummy data):
|
||||
// Line is a sequence of points:
|
||||
algorithm = (line) -> Arrays.asList(1.1, 2.2);
|
||||
}
|
||||
}
|
||||
@ -35,8 +36,8 @@ class Bisection extends FindMinima {
|
||||
// The "Context" controls the strategy:
|
||||
class MinimaSolver {
|
||||
private FindMinima strategy;
|
||||
MinimaSolver(FindMinima strat) {
|
||||
strategy = strat;
|
||||
MinimaSolver(FindMinima strategy) {
|
||||
this.strategy = strategy;
|
||||
}
|
||||
List<Double> minima(List<Double> line) {
|
||||
return strategy.algorithm.apply(line);
|
||||
@ -54,11 +55,14 @@ public class StrategyPattern {
|
||||
1.0, 2.0, 1.0, 2.0, -1.0,
|
||||
3.0, 4.0, 5.0, 4.0 );
|
||||
System.out.println(solver.minima(line));
|
||||
solver.changeAlgorithm(new Perturbation());
|
||||
System.out.println(solver.minima(line));
|
||||
solver.changeAlgorithm(new Bisection());
|
||||
System.out.println(solver.minima(line));
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
[1.1, 2.2]
|
||||
[3.3, 4.4]
|
||||
[5.5, 6.6]
|
||||
*/
|
||||
|
@ -9,6 +9,7 @@ import java.util.*;
|
||||
|
||||
// "Context" is now incorporated:
|
||||
class FindMinima2 {
|
||||
private
|
||||
Function<List<Double>, List<Double>> algorithm;
|
||||
FindMinima2() { leastSquares(); } // default
|
||||
// The various strategies:
|
||||
@ -33,11 +34,14 @@ public class StrategyPattern2 {
|
||||
1.0, 2.0, 1.0, 2.0, -1.0,
|
||||
3.0, 4.0, 5.0, 4.0 );
|
||||
System.out.println(solver.minima(line));
|
||||
solver.perturbation();
|
||||
System.out.println(solver.minima(line));
|
||||
solver.bisection();
|
||||
System.out.println(solver.minima(line));
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
[1.1, 2.2]
|
||||
[3.3, 4.4]
|
||||
[5.5, 6.6]
|
||||
*/
|
||||
|
@ -5,10 +5,12 @@
|
||||
package patterns.trash;
|
||||
|
||||
public class Aluminum extends Trash {
|
||||
private static double val = 1.67f;
|
||||
public Aluminum(double wt) { super(wt); }
|
||||
@Override public double value() { return val; }
|
||||
public static void value(double newVal) {
|
||||
val = newVal;
|
||||
@Override public double price() {
|
||||
return Price.ALUMINUM;
|
||||
}
|
||||
// Ignore for now; to be used later:
|
||||
@Override public void accept(Visitor v) {
|
||||
v.visit(this);
|
||||
}
|
||||
}
|
||||
|
35
patterns/trash/Bins.java
Normal file
35
patterns/trash/Bins.java
Normal 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");
|
||||
}
|
||||
}
|
@ -5,10 +5,12 @@
|
||||
package patterns.trash;
|
||||
|
||||
public class Cardboard extends Trash {
|
||||
private static double val = 0.23f;
|
||||
public Cardboard(double wt) { super(wt); }
|
||||
@Override public double value() { return val; }
|
||||
public static void value(double newVal) {
|
||||
val = newVal;
|
||||
@Override public double price() {
|
||||
return Price.CARDBOARD;
|
||||
}
|
||||
// Ignore for now; to be used later:
|
||||
@Override public void accept(Visitor v) {
|
||||
v.visit(this);
|
||||
}
|
||||
}
|
||||
|
20
patterns/trash/ClassToListOfTrashMap.java
Normal file
20
patterns/trash/ClassToListOfTrashMap.java
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
44
patterns/trash/DynaFactory.java
Normal file
44
patterns/trash/DynaFactory.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
// (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.
|
||||
// Any object that can be filled with Trash
|
||||
// Any object that can be filled with Trash.
|
||||
package patterns.trash;
|
||||
|
||||
public interface Fillable<T extends Trash> {
|
||||
|
@ -2,15 +2,17 @@
|
||||
// (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.
|
||||
// Adapter that makes a List Fillable
|
||||
// Adapter that makes a List Fillable.
|
||||
package patterns.trash;
|
||||
import java.util.*;
|
||||
|
||||
public class FillableList<T extends Trash>
|
||||
implements Fillable<T> {
|
||||
private List<T> v;
|
||||
public FillableList(List<T> vv) {
|
||||
v = vv;
|
||||
private List<T> list;
|
||||
public FillableList(List<T> list) {
|
||||
this.list = list;
|
||||
}
|
||||
@Override public void addTrash(T t) {
|
||||
list.add(t);
|
||||
}
|
||||
@Override public void addTrash(T t) { v.add(t); }
|
||||
}
|
||||
|
@ -5,10 +5,12 @@
|
||||
package patterns.trash;
|
||||
|
||||
public class Glass extends Trash {
|
||||
private static double val = 0.23f;
|
||||
public Glass(double wt) { super(wt); }
|
||||
@Override public double value() { return val; }
|
||||
public static void value(double newVal) {
|
||||
val = newVal;
|
||||
@Override public double price() {
|
||||
return Price.GLASS;
|
||||
}
|
||||
// Ignore for now; to be used later:
|
||||
@Override public void accept(Visitor v) {
|
||||
v.visit(this);
|
||||
}
|
||||
}
|
||||
|
41
patterns/trash/GroupingBy.java
Normal file
41
patterns/trash/GroupingBy.java
Normal 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
|
||||
*/
|
@ -5,10 +5,12 @@
|
||||
package patterns.trash;
|
||||
|
||||
public class Paper extends Trash {
|
||||
private static double val = 0.10f;
|
||||
public Paper(double wt) { super(wt); }
|
||||
@Override public double value() { return val; }
|
||||
public static void value(double newVal) {
|
||||
val = newVal;
|
||||
@Override public double price() {
|
||||
return Price.PAPER;
|
||||
}
|
||||
// Ignore for now; to be used later:
|
||||
@Override public void accept(Visitor v) {
|
||||
v.visit(this);
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
// (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.
|
||||
// Open a file and parse its contents into
|
||||
// Trash objects, placing each into a List
|
||||
// Opens a file and parses its contents into
|
||||
// Trash objects, placing each into a Fillable.
|
||||
// {java patterns.trash.ParseTrash}
|
||||
package patterns.trash;
|
||||
import java.util.*;
|
||||
@ -13,79 +13,56 @@ import java.nio.file.*;
|
||||
import java.nio.file.Files;
|
||||
|
||||
public class ParseTrash {
|
||||
public static String source = "Trash.dat";
|
||||
public static <T extends Trash> void
|
||||
fillBin(String pckg, Fillable<T> bin) {
|
||||
fillBin(String packageName, Fillable<T> bin) {
|
||||
DynaFactory factory =
|
||||
new DynaFactory(packageName);
|
||||
try {
|
||||
Files.lines(Paths.get("trash", "Trash.dat"))
|
||||
// Remove empty lines and comment lines:
|
||||
Files.lines(Paths.get("trash", source))
|
||||
// Remove comments and empty lines:
|
||||
.filter(line -> line.trim().length() != 0)
|
||||
.filter(line -> !line.startsWith("//"))
|
||||
.forEach(line -> {
|
||||
String type = "patterns." + pckg + "." +
|
||||
line.substring(
|
||||
String type = line.substring(
|
||||
0, line.indexOf(':')).trim();
|
||||
double weight = Double.valueOf(
|
||||
line.substring(line.indexOf(':') + 1)
|
||||
.trim());
|
||||
bin.addTrash(Trash.factory(
|
||||
new Trash.Info(type, weight)));
|
||||
bin.addTrash(factory.create(
|
||||
new TrashInfo(type, weight)));
|
||||
});
|
||||
} catch(IOException |
|
||||
NumberFormatException |
|
||||
Trash.TrashClassNotFoundException |
|
||||
Trash.CannotCreateTrashException e) {
|
||||
} catch(IOException | NumberFormatException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
// Special case to handle List:
|
||||
// Special case to handle a List:
|
||||
public static <T extends Trash> void
|
||||
fillBin(String pckg, List<T> bin) {
|
||||
fillBin(pckg, new FillableList<>(bin));
|
||||
fillBin(String packageName, List<T> bin) {
|
||||
fillBin(packageName, new FillableList<>(bin));
|
||||
}
|
||||
// Basic test:
|
||||
public static void main(String[] args) {
|
||||
List<Trash> t = new ArrayList<>();
|
||||
fillBin("trash", t);
|
||||
t.forEach(System.out::println);
|
||||
List<Trash> bin = new ArrayList<>();
|
||||
fillBin("trash", bin);
|
||||
bin.forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
Loading patterns.trash.Glass
|
||||
Loading patterns.trash.Cardboard
|
||||
Loading patterns.trash.Paper
|
||||
Loading patterns.trash.Aluminum
|
||||
Loading patterns.trash.Cardboard
|
||||
patterns.trash.Glass w:54.0 v:0.23
|
||||
patterns.trash.Paper w:22.0 v:0.10
|
||||
patterns.trash.Paper w:11.0 v:0.10
|
||||
patterns.trash.Glass w:17.0 v:0.23
|
||||
patterns.trash.Aluminum w:89.0 v:1.67
|
||||
patterns.trash.Paper w:88.0 v:0.10
|
||||
patterns.trash.Aluminum w:76.0 v:1.67
|
||||
patterns.trash.Cardboard w:96.0 v:0.23
|
||||
patterns.trash.Aluminum w:25.0 v:1.67
|
||||
patterns.trash.Aluminum w:34.0 v:1.67
|
||||
patterns.trash.Glass w:11.0 v:0.23
|
||||
patterns.trash.Glass w:68.0 v:0.23
|
||||
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
|
||||
Loading patterns.trash.Glass
|
||||
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
|
||||
*/
|
||||
|
13
patterns/trash/Price.java
Normal file
13
patterns/trash/Price.java
Normal 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;
|
||||
}
|
@ -1,35 +1,13 @@
|
||||
// patterns/trash/Trash.dat
|
||||
Glass:54
|
||||
Paper:22
|
||||
Paper:11
|
||||
Glass:17
|
||||
Aluminum:89
|
||||
Paper:88
|
||||
Aluminum:76
|
||||
Cardboard:96
|
||||
Aluminum:25
|
||||
Aluminum:34
|
||||
Glass:11
|
||||
Glass:68
|
||||
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
|
||||
Cardboard:4.4
|
||||
Paper:8.0
|
||||
Aluminum:1.8
|
||||
Glass:5.4
|
||||
Aluminum:3.4
|
||||
Cardboard:2.2
|
||||
Glass:4.3
|
||||
Cardboard:1.2
|
||||
Paper:6.6
|
||||
Aluminum:2.7
|
||||
Paper:9.1
|
||||
Glass:3.6
|
||||
|
@ -2,90 +2,21 @@
|
||||
// (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.
|
||||
// Base class for Trash recycling examples
|
||||
// Base class for Trash recycling examples.
|
||||
package patterns.trash;
|
||||
import java.util.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
public abstract class Trash {
|
||||
private double weight;
|
||||
public Trash(double wt) { weight = wt; }
|
||||
public Trash() {}
|
||||
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 final double weight;
|
||||
public Trash(double weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
public abstract double price();
|
||||
@Override public String toString() {
|
||||
// Print correct subclass name:
|
||||
return getClass().getName() +
|
||||
" w:" + weight() + " v:" +
|
||||
String.format("%.2f", value());
|
||||
}
|
||||
// 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);
|
||||
return String.format(
|
||||
"%s weight: %.2f * price: %.2f = %.2f",
|
||||
getClass().getSimpleName(),
|
||||
weight, price(), weight * price());
|
||||
}
|
||||
// Ignore for now; to be used later:
|
||||
public abstract void accept(Visitor v);
|
||||
}
|
||||
|
18
patterns/trash/TrashInfo.java
Normal file
18
patterns/trash/TrashInfo.java
Normal 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 + ")";
|
||||
}
|
||||
}
|
21
patterns/trash/TrashValue.java
Normal file
21
patterns/trash/TrashValue.java
Normal 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);
|
||||
}
|
||||
}
|
104
patterns/trash/TrashVisitor.java
Normal file
104
patterns/trash/TrashVisitor.java
Normal 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
|
||||
*/
|
52
patterns/trash/TypeMapTrash.java
Normal file
52
patterns/trash/TypeMapTrash.java
Normal 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
|
||||
*/
|
31
patterns/trash/Visitor.java
Normal file
31
patterns/trash/Visitor.java
Normal 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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
||||
*/
|
@ -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);
|
||||
}
|
@ -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();
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
// (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.
|
||||
// Demonstration of "visitor" pattern
|
||||
// Demonstration of the Visitor pattern.
|
||||
// {java patterns.visitor.BeeAndFlowers}
|
||||
package patterns.visitor;
|
||||
import java.util.*;
|
||||
@ -11,7 +11,7 @@ import java.util.stream.*;
|
||||
|
||||
interface Visitor {
|
||||
void visit(Gladiolus g);
|
||||
void visit(Renuculus r);
|
||||
void visit(Ranunculus r);
|
||||
void visit(Chrysanthemum c);
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ class Gladiolus implements Flower {
|
||||
public void accept(Visitor v) { v.visit(this);}
|
||||
}
|
||||
|
||||
class Renuculus implements Flower {
|
||||
class Ranunculus implements Flower {
|
||||
@Override
|
||||
public void accept(Visitor v) { v.visit(this);}
|
||||
}
|
||||
@ -37,13 +37,13 @@ class Chrysanthemum implements Flower {
|
||||
|
||||
// Add the ability to produce a String:
|
||||
class StringVal implements Visitor {
|
||||
String s;
|
||||
private String s;
|
||||
@Override public String toString() { return s; }
|
||||
@Override public void visit(Gladiolus g) {
|
||||
s = "Gladiolus";
|
||||
}
|
||||
@Override public void visit(Renuculus r) {
|
||||
s = "Renuculus";
|
||||
@Override public void visit(Ranunculus r) {
|
||||
s = "Ranunculus";
|
||||
}
|
||||
@Override public void visit(Chrysanthemum c) {
|
||||
s = "Chrysanthemum";
|
||||
@ -55,8 +55,8 @@ class Bee implements Visitor {
|
||||
@Override public void visit(Gladiolus g) {
|
||||
System.out.println("Bee and Gladiolus");
|
||||
}
|
||||
@Override public void visit(Renuculus r) {
|
||||
System.out.println("Bee and Renuculus");
|
||||
@Override public void visit(Ranunculus r) {
|
||||
System.out.println("Bee and Ranunculus");
|
||||
}
|
||||
@Override public void visit(Chrysanthemum c) {
|
||||
System.out.println("Bee and Chrysanthemum");
|
||||
@ -66,7 +66,7 @@ class Bee implements Visitor {
|
||||
class FlowerFactory {
|
||||
static List<Supplier<Flower>> flowers =
|
||||
Arrays.asList(Gladiolus::new,
|
||||
Renuculus::new, Chrysanthemum::new);
|
||||
Ranunculus::new, Chrysanthemum::new);
|
||||
static final int SZ = flowers.size();
|
||||
private static SplittableRandom rand =
|
||||
new SplittableRandom(47);
|
||||
@ -95,21 +95,21 @@ public class BeeAndFlowers {
|
||||
Gladiolus
|
||||
Chrysanthemum
|
||||
Gladiolus
|
||||
Renuculus
|
||||
Ranunculus
|
||||
Chrysanthemum
|
||||
Renuculus
|
||||
Ranunculus
|
||||
Chrysanthemum
|
||||
Chrysanthemum
|
||||
Chrysanthemum
|
||||
Renuculus
|
||||
Ranunculus
|
||||
Bee and Gladiolus
|
||||
Bee and Chrysanthemum
|
||||
Bee and Gladiolus
|
||||
Bee and Renuculus
|
||||
Bee and Ranunculus
|
||||
Bee and Chrysanthemum
|
||||
Bee and Renuculus
|
||||
Bee and Ranunculus
|
||||
Bee and Chrysanthemum
|
||||
Bee and Chrysanthemum
|
||||
Bee and Chrysanthemum
|
||||
Bee and Renuculus
|
||||
Bee and Ranunculus
|
||||
*/
|
||||
|
@ -1,8 +1,7 @@
|
||||
// polymorphism/RTTI.java
|
||||
// polymorphism/Reflect.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.
|
||||
// Downcasting & Runtime type information (RTTI)
|
||||
// {ThrowsException}
|
||||
|
||||
class Useful {
|
||||
@ -18,7 +17,7 @@ class MoreUseful extends Useful {
|
||||
public void w() {}
|
||||
}
|
||||
|
||||
public class RTTI {
|
||||
public class Reflect {
|
||||
public static void main(String[] args) {
|
||||
Useful[] x = {
|
||||
new Useful(),
|
||||
@ -28,7 +27,7 @@ public class RTTI {
|
||||
x[1].g();
|
||||
// Compile time: method not found in Useful:
|
||||
//- x[1].u();
|
||||
((MoreUseful)x[1]).u(); // Downcast/RTTI
|
||||
((MoreUseful)x[1]).u(); // Downcast/Reflect
|
||||
((MoreUseful)x[0]).u(); // Exception thrown
|
||||
}
|
||||
}
|
||||
@ -37,5 +36,5 @@ ___[ Error Output ]___
|
||||
Exception in thread "main"
|
||||
java.lang.ClassCastException: Useful cannot be cast to
|
||||
MoreUseful
|
||||
at RTTI.main(RTTI.java:29)
|
||||
at Reflect.main(Reflect.java:28)
|
||||
*/
|
@ -13,7 +13,7 @@ class FruitQualities {
|
||||
private int ripeness;
|
||||
private int smell;
|
||||
// etc.
|
||||
// No-arg constructor:
|
||||
// Zero-argument constructor:
|
||||
FruitQualities() {
|
||||
// Do something meaningful...
|
||||
}
|
||||
@ -32,7 +32,7 @@ class FruitQualities {
|
||||
|
||||
class Seed {
|
||||
// Members...
|
||||
Seed() { /* No-arg constructor */ }
|
||||
Seed() { /* Zero-argument constructor */ }
|
||||
Seed(Seed s) { /* Copy constructor */ }
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ class Tomato extends Fruit {
|
||||
|
||||
class ZebraQualities extends FruitQualities {
|
||||
private int stripedness;
|
||||
// No-arg constructor:
|
||||
// Zero-argument constructor:
|
||||
ZebraQualities() {
|
||||
super();
|
||||
// do something meaningful...
|
||||
@ -117,7 +117,7 @@ public class CopyConstructor {
|
||||
t.getClass().getName());
|
||||
}
|
||||
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 " +
|
||||
f.getClass().getName());
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
// typeinfo/AnonymousImplementation.java
|
||||
// reflection/AnonymousImplementation.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.
|
||||
// Anonymous inner classes can't hide from reflection
|
||||
import typeinfo.interfacea.*;
|
||||
import reflection.interfacea.*;
|
||||
|
||||
class AnonymousA {
|
||||
public static A makeA() {
|
@ -1,4 +1,4 @@
|
||||
// typeinfo/BoundedClassReferences.java
|
||||
// reflection/BoundedClassReferences.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.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user