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 class AdapterMethodIdiom {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
ReversibleArrayList<String> ral =
|
ReversibleArrayList<String> ral =
|
||||||
new ReversibleArrayList<String>(
|
new ReversibleArrayList<>(
|
||||||
Arrays.asList("To be or not to be".split(" ")));
|
Arrays.asList("To be or not to be".split(" ")));
|
||||||
// Grabs the ordinary iterator via iterator():
|
// Grabs the ordinary iterator via iterator():
|
||||||
for(String s : ral)
|
for(String s : ral)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class CollectionSequence
|
public class CollectionSequence
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class CrossCollectionIteration {
|
public class CrossCollectionIteration {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class CrossCollectionIteration2 {
|
public class CrossCollectionIteration2 {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class InterfaceVsIterator {
|
public class InterfaceVsIterator {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class LinkedListFeatures {
|
public class LinkedListFeatures {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class ListFeatures {
|
public class ListFeatures {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class ListIteration {
|
public class ListIteration {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// {java collections.MapOfList}
|
// {java collections.MapOfList}
|
||||||
package collections;
|
package collections;
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class MapOfList {
|
public class MapOfList {
|
||||||
|
@ -29,7 +29,7 @@ public class MultiIterableClass extends IterableClass {
|
|||||||
return new Iterable<String>() {
|
return new Iterable<String>() {
|
||||||
public Iterator<String> iterator() {
|
public Iterator<String> iterator() {
|
||||||
List<String> shuffled =
|
List<String> shuffled =
|
||||||
new ArrayList<String>(Arrays.asList(words));
|
new ArrayList<>(Arrays.asList(words));
|
||||||
Collections.shuffle(shuffled, new Random(47));
|
Collections.shuffle(shuffled, new Random(47));
|
||||||
return shuffled.iterator();
|
return shuffled.iterator();
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
class PetSequence {
|
class PetSequence {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class PetMap {
|
public class PetMap {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class SimpleIteration {
|
public class SimpleIteration {
|
||||||
|
@ -56,8 +56,7 @@ public class CollectionMethods {
|
|||||||
// c2 and c3 (an intersection of sets):
|
// c2 and c3 (an intersection of sets):
|
||||||
c2.retainAll(c3);
|
c2.retainAll(c3);
|
||||||
show(c2);
|
show(c2);
|
||||||
// Throw away all the elements
|
// Discard all c2 elements that also appear in c3:
|
||||||
// in c2 that also appear in c3:
|
|
||||||
c2.removeAll(c3);
|
c2.removeAll(c3);
|
||||||
System.out.println(
|
System.out.println(
|
||||||
"c2.isEmpty() = " + c2.isEmpty());
|
"c2.isEmpty() = " + c2.isEmpty());
|
||||||
|
@ -1,12 +1,512 @@
|
|||||||
|
0: ForkJoinPool.commonPool-worker-1
|
||||||
0: main
|
0: main
|
||||||
1: main
|
2: main
|
||||||
1: ForkJoinPool.commonPool-worker-3
|
2: ForkJoinPool.commonPool-worker-1
|
||||||
1: ForkJoinPool.commonPool-worker-5
|
|
||||||
3: ForkJoinPool.commonPool-worker-5
|
|
||||||
3: main
|
3: main
|
||||||
5: ForkJoinPool.commonPool-worker-5
|
4: ForkJoinPool.commonPool-worker-1
|
||||||
5: main
|
5: main
|
||||||
7: ForkJoinPool.commonPool-worker-5
|
6: ForkJoinPool.commonPool-worker-1
|
||||||
8: main
|
7: main
|
||||||
8: ForkJoinPool.commonPool-worker-3
|
9: ForkJoinPool.commonPool-worker-1
|
||||||
10: ForkJoinPool.commonPool-worker-5
|
9: main
|
||||||
|
11: ForkJoinPool.commonPool-worker-1
|
||||||
|
11: main
|
||||||
|
12: ForkJoinPool.commonPool-worker-1
|
||||||
|
13: main
|
||||||
|
15: ForkJoinPool.commonPool-worker-1
|
||||||
|
15: main
|
||||||
|
17: main
|
||||||
|
18: main
|
||||||
|
19: main
|
||||||
|
20: main
|
||||||
|
21: main
|
||||||
|
17: ForkJoinPool.commonPool-worker-1
|
||||||
|
23: main
|
||||||
|
23: ForkJoinPool.commonPool-worker-1
|
||||||
|
24: main
|
||||||
|
25: ForkJoinPool.commonPool-worker-1
|
||||||
|
26: main
|
||||||
|
27: ForkJoinPool.commonPool-worker-1
|
||||||
|
28: main
|
||||||
|
29: ForkJoinPool.commonPool-worker-1
|
||||||
|
30: main
|
||||||
|
32: main
|
||||||
|
32: ForkJoinPool.commonPool-worker-1
|
||||||
|
33: main
|
||||||
|
35: ForkJoinPool.commonPool-worker-1
|
||||||
|
36: ForkJoinPool.commonPool-worker-1
|
||||||
|
37: ForkJoinPool.commonPool-worker-1
|
||||||
|
38: ForkJoinPool.commonPool-worker-1
|
||||||
|
35: main
|
||||||
|
39: ForkJoinPool.commonPool-worker-1
|
||||||
|
41: ForkJoinPool.commonPool-worker-1
|
||||||
|
40: main
|
||||||
|
42: ForkJoinPool.commonPool-worker-1
|
||||||
|
43: main
|
||||||
|
44: ForkJoinPool.commonPool-worker-1
|
||||||
|
45: main
|
||||||
|
46: ForkJoinPool.commonPool-worker-1
|
||||||
|
47: main
|
||||||
|
49: main
|
||||||
|
50: main
|
||||||
|
50: ForkJoinPool.commonPool-worker-1
|
||||||
|
51: main
|
||||||
|
52: ForkJoinPool.commonPool-worker-1
|
||||||
|
53: main
|
||||||
|
55: ForkJoinPool.commonPool-worker-1
|
||||||
|
55: main
|
||||||
|
56: ForkJoinPool.commonPool-worker-1
|
||||||
|
58: ForkJoinPool.commonPool-worker-1
|
||||||
|
57: main
|
||||||
|
59: ForkJoinPool.commonPool-worker-1
|
||||||
|
60: main
|
||||||
|
61: ForkJoinPool.commonPool-worker-1
|
||||||
|
62: main
|
||||||
|
63: ForkJoinPool.commonPool-worker-1
|
||||||
|
64: main
|
||||||
|
65: ForkJoinPool.commonPool-worker-1
|
||||||
|
66: main
|
||||||
|
67: ForkJoinPool.commonPool-worker-1
|
||||||
|
68: main
|
||||||
|
69: ForkJoinPool.commonPool-worker-1
|
||||||
|
71: ForkJoinPool.commonPool-worker-1
|
||||||
|
72: ForkJoinPool.commonPool-worker-1
|
||||||
|
70: main
|
||||||
|
73: ForkJoinPool.commonPool-worker-1
|
||||||
|
75: ForkJoinPool.commonPool-worker-1
|
||||||
|
76: ForkJoinPool.commonPool-worker-1
|
||||||
|
74: main
|
||||||
|
77: ForkJoinPool.commonPool-worker-1
|
||||||
|
78: ForkJoinPool.commonPool-worker-1
|
||||||
|
79: main
|
||||||
|
80: ForkJoinPool.commonPool-worker-1
|
||||||
|
81: main
|
||||||
|
82: ForkJoinPool.commonPool-worker-1
|
||||||
|
83: main
|
||||||
|
84: ForkJoinPool.commonPool-worker-1
|
||||||
|
85: main
|
||||||
|
86: ForkJoinPool.commonPool-worker-1
|
||||||
|
87: main
|
||||||
|
89: ForkJoinPool.commonPool-worker-1
|
||||||
|
90: ForkJoinPool.commonPool-worker-1
|
||||||
|
89: main
|
||||||
|
91: ForkJoinPool.commonPool-worker-1
|
||||||
|
92: main
|
||||||
|
93: ForkJoinPool.commonPool-worker-1
|
||||||
|
94: main
|
||||||
|
95: ForkJoinPool.commonPool-worker-1
|
||||||
|
96: main
|
||||||
|
98: main
|
||||||
|
97: ForkJoinPool.commonPool-worker-1
|
||||||
|
99: main
|
||||||
|
100: ForkJoinPool.commonPool-worker-1
|
||||||
|
101: main
|
||||||
|
103: ForkJoinPool.commonPool-worker-1
|
||||||
|
103: main
|
||||||
|
104: ForkJoinPool.commonPool-worker-1
|
||||||
|
106: ForkJoinPool.commonPool-worker-1
|
||||||
|
107: ForkJoinPool.commonPool-worker-1
|
||||||
|
106: main
|
||||||
|
108: ForkJoinPool.commonPool-worker-1
|
||||||
|
110: ForkJoinPool.commonPool-worker-1
|
||||||
|
108: ForkJoinPool.commonPool-worker-2
|
||||||
|
111: ForkJoinPool.commonPool-worker-1
|
||||||
|
110: main
|
||||||
|
113: ForkJoinPool.commonPool-worker-1
|
||||||
|
112: ForkJoinPool.commonPool-worker-2
|
||||||
|
115: ForkJoinPool.commonPool-worker-1
|
||||||
|
116: main
|
||||||
|
116: ForkJoinPool.commonPool-worker-2
|
||||||
|
117: ForkJoinPool.commonPool-worker-1
|
||||||
|
118: main
|
||||||
|
119: ForkJoinPool.commonPool-worker-2
|
||||||
|
120: ForkJoinPool.commonPool-worker-1
|
||||||
|
121: main
|
||||||
|
123: ForkJoinPool.commonPool-worker-1
|
||||||
|
124: main
|
||||||
|
124: ForkJoinPool.commonPool-worker-2
|
||||||
|
126: main
|
||||||
|
126: ForkJoinPool.commonPool-worker-1
|
||||||
|
127: ForkJoinPool.commonPool-worker-2
|
||||||
|
128: main
|
||||||
|
130: ForkJoinPool.commonPool-worker-1
|
||||||
|
130: ForkJoinPool.commonPool-worker-2
|
||||||
|
131: main
|
||||||
|
133: ForkJoinPool.commonPool-worker-1
|
||||||
|
134: ForkJoinPool.commonPool-worker-2
|
||||||
|
134: main
|
||||||
|
136: ForkJoinPool.commonPool-worker-1
|
||||||
|
137: main
|
||||||
|
137: ForkJoinPool.commonPool-worker-2
|
||||||
|
138: ForkJoinPool.commonPool-worker-1
|
||||||
|
140: main
|
||||||
|
140: ForkJoinPool.commonPool-worker-2
|
||||||
|
141: ForkJoinPool.commonPool-worker-1
|
||||||
|
143: main
|
||||||
|
143: ForkJoinPool.commonPool-worker-2
|
||||||
|
145: ForkJoinPool.commonPool-worker-1
|
||||||
|
146: main
|
||||||
|
146: ForkJoinPool.commonPool-worker-2
|
||||||
|
148: ForkJoinPool.commonPool-worker-1
|
||||||
|
149: main
|
||||||
|
149: ForkJoinPool.commonPool-worker-2
|
||||||
|
151: ForkJoinPool.commonPool-worker-1
|
||||||
|
152: ForkJoinPool.commonPool-worker-2
|
||||||
|
154: ForkJoinPool.commonPool-worker-1
|
||||||
|
154: ForkJoinPool.commonPool-worker-2
|
||||||
|
152: main
|
||||||
|
156: ForkJoinPool.commonPool-worker-1
|
||||||
|
156: ForkJoinPool.commonPool-worker-2
|
||||||
|
159: ForkJoinPool.commonPool-worker-1
|
||||||
|
159: ForkJoinPool.commonPool-worker-2
|
||||||
|
161: ForkJoinPool.commonPool-worker-1
|
||||||
|
159: main
|
||||||
|
162: ForkJoinPool.commonPool-worker-1
|
||||||
|
161: ForkJoinPool.commonPool-worker-2
|
||||||
|
164: ForkJoinPool.commonPool-worker-1
|
||||||
|
163: main
|
||||||
|
166: ForkJoinPool.commonPool-worker-1
|
||||||
|
168: ForkJoinPool.commonPool-worker-1
|
||||||
|
168: main
|
||||||
|
169: ForkJoinPool.commonPool-worker-1
|
||||||
|
170: main
|
||||||
|
167: ForkJoinPool.commonPool-worker-2
|
||||||
|
171: ForkJoinPool.commonPool-worker-1
|
||||||
|
172: main
|
||||||
|
168: ForkJoinPool.commonPool-worker-3
|
||||||
|
174: ForkJoinPool.commonPool-worker-1
|
||||||
|
175: main
|
||||||
|
178: ForkJoinPool.commonPool-worker-1
|
||||||
|
178: main
|
||||||
|
178: ForkJoinPool.commonPool-worker-3
|
||||||
|
175: ForkJoinPool.commonPool-worker-2
|
||||||
|
179: ForkJoinPool.commonPool-worker-1
|
||||||
|
181: main
|
||||||
|
183: ForkJoinPool.commonPool-worker-1
|
||||||
|
183: ForkJoinPool.commonPool-worker-2
|
||||||
|
184: main
|
||||||
|
184: ForkJoinPool.commonPool-worker-3
|
||||||
|
185: ForkJoinPool.commonPool-worker-1
|
||||||
|
187: main
|
||||||
|
187: ForkJoinPool.commonPool-worker-2
|
||||||
|
189: ForkJoinPool.commonPool-worker-1
|
||||||
|
191: main
|
||||||
|
189: ForkJoinPool.commonPool-worker-3
|
||||||
|
191: ForkJoinPool.commonPool-worker-2
|
||||||
|
193: main
|
||||||
|
193: ForkJoinPool.commonPool-worker-1
|
||||||
|
195: ForkJoinPool.commonPool-worker-3
|
||||||
|
195: ForkJoinPool.commonPool-worker-2
|
||||||
|
197: main
|
||||||
|
199: ForkJoinPool.commonPool-worker-3
|
||||||
|
199: ForkJoinPool.commonPool-worker-2
|
||||||
|
197: ForkJoinPool.commonPool-worker-1
|
||||||
|
200: main
|
||||||
|
202: ForkJoinPool.commonPool-worker-3
|
||||||
|
203: ForkJoinPool.commonPool-worker-2
|
||||||
|
204: ForkJoinPool.commonPool-worker-1
|
||||||
|
204: main
|
||||||
|
205: ForkJoinPool.commonPool-worker-3
|
||||||
|
207: ForkJoinPool.commonPool-worker-2
|
||||||
|
208: ForkJoinPool.commonPool-worker-1
|
||||||
|
208: main
|
||||||
|
209: ForkJoinPool.commonPool-worker-3
|
||||||
|
211: ForkJoinPool.commonPool-worker-2
|
||||||
|
211: ForkJoinPool.commonPool-worker-1
|
||||||
|
213: main
|
||||||
|
213: ForkJoinPool.commonPool-worker-3
|
||||||
|
215: ForkJoinPool.commonPool-worker-2
|
||||||
|
215: ForkJoinPool.commonPool-worker-1
|
||||||
|
217: main
|
||||||
|
217: ForkJoinPool.commonPool-worker-3
|
||||||
|
219: ForkJoinPool.commonPool-worker-2
|
||||||
|
220: ForkJoinPool.commonPool-worker-1
|
||||||
|
221: main
|
||||||
|
221: ForkJoinPool.commonPool-worker-3
|
||||||
|
224: ForkJoinPool.commonPool-worker-1
|
||||||
|
225: main
|
||||||
|
225: ForkJoinPool.commonPool-worker-3
|
||||||
|
223: ForkJoinPool.commonPool-worker-2
|
||||||
|
227: ForkJoinPool.commonPool-worker-1
|
||||||
|
227: main
|
||||||
|
229: ForkJoinPool.commonPool-worker-3
|
||||||
|
229: ForkJoinPool.commonPool-worker-2
|
||||||
|
231: ForkJoinPool.commonPool-worker-1
|
||||||
|
231: main
|
||||||
|
233: ForkJoinPool.commonPool-worker-3
|
||||||
|
233: ForkJoinPool.commonPool-worker-2
|
||||||
|
235: ForkJoinPool.commonPool-worker-1
|
||||||
|
236: main
|
||||||
|
237: ForkJoinPool.commonPool-worker-3
|
||||||
|
237: ForkJoinPool.commonPool-worker-2
|
||||||
|
239: ForkJoinPool.commonPool-worker-1
|
||||||
|
241: main
|
||||||
|
241: ForkJoinPool.commonPool-worker-2
|
||||||
|
241: ForkJoinPool.commonPool-worker-3
|
||||||
|
243: ForkJoinPool.commonPool-worker-1
|
||||||
|
244: main
|
||||||
|
244: ForkJoinPool.commonPool-worker-2
|
||||||
|
245: ForkJoinPool.commonPool-worker-3
|
||||||
|
247: ForkJoinPool.commonPool-worker-1
|
||||||
|
249: ForkJoinPool.commonPool-worker-3
|
||||||
|
251: ForkJoinPool.commonPool-worker-3
|
||||||
|
250: ForkJoinPool.commonPool-worker-1
|
||||||
|
251: ForkJoinPool.commonPool-worker-2
|
||||||
|
253: ForkJoinPool.commonPool-worker-3
|
||||||
|
254: ForkJoinPool.commonPool-worker-1
|
||||||
|
254: ForkJoinPool.commonPool-worker-2
|
||||||
|
251: main
|
||||||
|
255: ForkJoinPool.commonPool-worker-3
|
||||||
|
257: ForkJoinPool.commonPool-worker-1
|
||||||
|
257: ForkJoinPool.commonPool-worker-2
|
||||||
|
259: ForkJoinPool.commonPool-worker-3
|
||||||
|
261: ForkJoinPool.commonPool-worker-1
|
||||||
|
261: ForkJoinPool.commonPool-worker-2
|
||||||
|
262: ForkJoinPool.commonPool-worker-3
|
||||||
|
263: ForkJoinPool.commonPool-worker-1
|
||||||
|
264: ForkJoinPool.commonPool-worker-2
|
||||||
|
265: ForkJoinPool.commonPool-worker-3
|
||||||
|
267: ForkJoinPool.commonPool-worker-1
|
||||||
|
267: ForkJoinPool.commonPool-worker-2
|
||||||
|
261: main
|
||||||
|
268: ForkJoinPool.commonPool-worker-3
|
||||||
|
269: ForkJoinPool.commonPool-worker-1
|
||||||
|
270: ForkJoinPool.commonPool-worker-2
|
||||||
|
272: ForkJoinPool.commonPool-worker-3
|
||||||
|
273: ForkJoinPool.commonPool-worker-1
|
||||||
|
276: ForkJoinPool.commonPool-worker-3
|
||||||
|
276: ForkJoinPool.commonPool-worker-1
|
||||||
|
274: ForkJoinPool.commonPool-worker-2
|
||||||
|
277: ForkJoinPool.commonPool-worker-3
|
||||||
|
279: ForkJoinPool.commonPool-worker-1
|
||||||
|
279: ForkJoinPool.commonPool-worker-2
|
||||||
|
275: main
|
||||||
|
281: ForkJoinPool.commonPool-worker-1
|
||||||
|
280: ForkJoinPool.commonPool-worker-3
|
||||||
|
282: ForkJoinPool.commonPool-worker-2
|
||||||
|
285: ForkJoinPool.commonPool-worker-1
|
||||||
|
286: ForkJoinPool.commonPool-worker-3
|
||||||
|
286: ForkJoinPool.commonPool-worker-2
|
||||||
|
288: ForkJoinPool.commonPool-worker-1
|
||||||
|
289: ForkJoinPool.commonPool-worker-3
|
||||||
|
289: ForkJoinPool.commonPool-worker-2
|
||||||
|
286: main
|
||||||
|
291: ForkJoinPool.commonPool-worker-1
|
||||||
|
292: ForkJoinPool.commonPool-worker-3
|
||||||
|
293: ForkJoinPool.commonPool-worker-2
|
||||||
|
293: main
|
||||||
|
296: ForkJoinPool.commonPool-worker-3
|
||||||
|
296: ForkJoinPool.commonPool-worker-2
|
||||||
|
297: main
|
||||||
|
297: ForkJoinPool.commonPool-worker-1
|
||||||
|
299: ForkJoinPool.commonPool-worker-3
|
||||||
|
299: ForkJoinPool.commonPool-worker-2
|
||||||
|
301: main
|
||||||
|
301: ForkJoinPool.commonPool-worker-1
|
||||||
|
303: ForkJoinPool.commonPool-worker-3
|
||||||
|
303: ForkJoinPool.commonPool-worker-2
|
||||||
|
305: main
|
||||||
|
305: ForkJoinPool.commonPool-worker-1
|
||||||
|
307: ForkJoinPool.commonPool-worker-3
|
||||||
|
307: ForkJoinPool.commonPool-worker-2
|
||||||
|
309: main
|
||||||
|
309: ForkJoinPool.commonPool-worker-1
|
||||||
|
311: ForkJoinPool.commonPool-worker-3
|
||||||
|
311: ForkJoinPool.commonPool-worker-2
|
||||||
|
313: main
|
||||||
|
313: ForkJoinPool.commonPool-worker-1
|
||||||
|
315: ForkJoinPool.commonPool-worker-3
|
||||||
|
315: ForkJoinPool.commonPool-worker-2
|
||||||
|
317: ForkJoinPool.commonPool-worker-1
|
||||||
|
319: ForkJoinPool.commonPool-worker-3
|
||||||
|
319: ForkJoinPool.commonPool-worker-2
|
||||||
|
320: ForkJoinPool.commonPool-worker-1
|
||||||
|
322: ForkJoinPool.commonPool-worker-3
|
||||||
|
317: main
|
||||||
|
323: ForkJoinPool.commonPool-worker-1
|
||||||
|
322: ForkJoinPool.commonPool-worker-2
|
||||||
|
324: ForkJoinPool.commonPool-worker-3
|
||||||
|
328: main
|
||||||
|
328: ForkJoinPool.commonPool-worker-3
|
||||||
|
328: ForkJoinPool.commonPool-worker-2
|
||||||
|
330: ForkJoinPool.commonPool-worker-3
|
||||||
|
329: main
|
||||||
|
331: ForkJoinPool.commonPool-worker-2
|
||||||
|
332: ForkJoinPool.commonPool-worker-3
|
||||||
|
334: ForkJoinPool.commonPool-worker-2
|
||||||
|
335: main
|
||||||
|
335: ForkJoinPool.commonPool-worker-3
|
||||||
|
337: ForkJoinPool.commonPool-worker-2
|
||||||
|
338: main
|
||||||
|
338: ForkJoinPool.commonPool-worker-3
|
||||||
|
340: ForkJoinPool.commonPool-worker-2
|
||||||
|
341: main
|
||||||
|
341: ForkJoinPool.commonPool-worker-3
|
||||||
|
343: ForkJoinPool.commonPool-worker-2
|
||||||
|
343: main
|
||||||
|
344: ForkJoinPool.commonPool-worker-3
|
||||||
|
346: ForkJoinPool.commonPool-worker-2
|
||||||
|
347: main
|
||||||
|
347: ForkJoinPool.commonPool-worker-3
|
||||||
|
349: ForkJoinPool.commonPool-worker-2
|
||||||
|
350: main
|
||||||
|
350: ForkJoinPool.commonPool-worker-3
|
||||||
|
351: ForkJoinPool.commonPool-worker-2
|
||||||
|
353: main
|
||||||
|
353: ForkJoinPool.commonPool-worker-3
|
||||||
|
355: ForkJoinPool.commonPool-worker-2
|
||||||
|
356: main
|
||||||
|
356: ForkJoinPool.commonPool-worker-3
|
||||||
|
358: ForkJoinPool.commonPool-worker-2
|
||||||
|
359: main
|
||||||
|
359: ForkJoinPool.commonPool-worker-3
|
||||||
|
361: ForkJoinPool.commonPool-worker-2
|
||||||
|
362: main
|
||||||
|
362: ForkJoinPool.commonPool-worker-3
|
||||||
|
365: main
|
||||||
|
364: ForkJoinPool.commonPool-worker-2
|
||||||
|
365: ForkJoinPool.commonPool-worker-3
|
||||||
|
366: main
|
||||||
|
368: ForkJoinPool.commonPool-worker-2
|
||||||
|
369: main
|
||||||
|
369: ForkJoinPool.commonPool-worker-3
|
||||||
|
372: ForkJoinPool.commonPool-worker-3
|
||||||
|
371: ForkJoinPool.commonPool-worker-2
|
||||||
|
372: main
|
||||||
|
374: ForkJoinPool.commonPool-worker-3
|
||||||
|
374: ForkJoinPool.commonPool-worker-2
|
||||||
|
376: ForkJoinPool.commonPool-worker-3
|
||||||
|
377: ForkJoinPool.commonPool-worker-2
|
||||||
|
378: ForkJoinPool.commonPool-worker-3
|
||||||
|
376: main
|
||||||
|
379: ForkJoinPool.commonPool-worker-2
|
||||||
|
380: ForkJoinPool.commonPool-worker-3
|
||||||
|
382: ForkJoinPool.commonPool-worker-2
|
||||||
|
383: ForkJoinPool.commonPool-worker-3
|
||||||
|
384: ForkJoinPool.commonPool-worker-2
|
||||||
|
385: ForkJoinPool.commonPool-worker-3
|
||||||
|
383: main
|
||||||
|
386: ForkJoinPool.commonPool-worker-2
|
||||||
|
387: ForkJoinPool.commonPool-worker-3
|
||||||
|
390: ForkJoinPool.commonPool-worker-2
|
||||||
|
390: ForkJoinPool.commonPool-worker-3
|
||||||
|
392: ForkJoinPool.commonPool-worker-2
|
||||||
|
392: ForkJoinPool.commonPool-worker-3
|
||||||
|
390: main
|
||||||
|
394: ForkJoinPool.commonPool-worker-2
|
||||||
|
394: ForkJoinPool.commonPool-worker-3
|
||||||
|
397: ForkJoinPool.commonPool-worker-2
|
||||||
|
397: ForkJoinPool.commonPool-worker-3
|
||||||
|
399: ForkJoinPool.commonPool-worker-2
|
||||||
|
397: main
|
||||||
|
400: ForkJoinPool.commonPool-worker-3
|
||||||
|
401: ForkJoinPool.commonPool-worker-3
|
||||||
|
401: ForkJoinPool.commonPool-worker-2
|
||||||
|
404: ForkJoinPool.commonPool-worker-3
|
||||||
|
404: ForkJoinPool.commonPool-worker-2
|
||||||
|
403: main
|
||||||
|
406: ForkJoinPool.commonPool-worker-3
|
||||||
|
406: ForkJoinPool.commonPool-worker-2
|
||||||
|
408: main
|
||||||
|
409: ForkJoinPool.commonPool-worker-3
|
||||||
|
409: ForkJoinPool.commonPool-worker-2
|
||||||
|
411: main
|
||||||
|
412: ForkJoinPool.commonPool-worker-3
|
||||||
|
412: ForkJoinPool.commonPool-worker-2
|
||||||
|
414: main
|
||||||
|
414: ForkJoinPool.commonPool-worker-3
|
||||||
|
415: ForkJoinPool.commonPool-worker-2
|
||||||
|
418: ForkJoinPool.commonPool-worker-3
|
||||||
|
418: ForkJoinPool.commonPool-worker-2
|
||||||
|
419: ForkJoinPool.commonPool-worker-3
|
||||||
|
420: ForkJoinPool.commonPool-worker-2
|
||||||
|
421: ForkJoinPool.commonPool-worker-3
|
||||||
|
422: ForkJoinPool.commonPool-worker-2
|
||||||
|
423: ForkJoinPool.commonPool-worker-3
|
||||||
|
424: ForkJoinPool.commonPool-worker-2
|
||||||
|
425: ForkJoinPool.commonPool-worker-3
|
||||||
|
426: ForkJoinPool.commonPool-worker-2
|
||||||
|
427: ForkJoinPool.commonPool-worker-3
|
||||||
|
428: ForkJoinPool.commonPool-worker-2
|
||||||
|
430: ForkJoinPool.commonPool-worker-2
|
||||||
|
430: ForkJoinPool.commonPool-worker-3
|
||||||
|
432: ForkJoinPool.commonPool-worker-3
|
||||||
|
432: ForkJoinPool.commonPool-worker-2
|
||||||
|
433: ForkJoinPool.commonPool-worker-3
|
||||||
|
434: ForkJoinPool.commonPool-worker-2
|
||||||
|
435: ForkJoinPool.commonPool-worker-3
|
||||||
|
436: ForkJoinPool.commonPool-worker-2
|
||||||
|
437: ForkJoinPool.commonPool-worker-3
|
||||||
|
438: ForkJoinPool.commonPool-worker-2
|
||||||
|
439: ForkJoinPool.commonPool-worker-3
|
||||||
|
440: ForkJoinPool.commonPool-worker-2
|
||||||
|
441: ForkJoinPool.commonPool-worker-3
|
||||||
|
442: ForkJoinPool.commonPool-worker-2
|
||||||
|
443: ForkJoinPool.commonPool-worker-3
|
||||||
|
444: ForkJoinPool.commonPool-worker-2
|
||||||
|
445: ForkJoinPool.commonPool-worker-3
|
||||||
|
446: ForkJoinPool.commonPool-worker-2
|
||||||
|
447: ForkJoinPool.commonPool-worker-3
|
||||||
|
448: ForkJoinPool.commonPool-worker-2
|
||||||
|
449: ForkJoinPool.commonPool-worker-3
|
||||||
|
450: ForkJoinPool.commonPool-worker-2
|
||||||
|
451: ForkJoinPool.commonPool-worker-3
|
||||||
|
452: ForkJoinPool.commonPool-worker-2
|
||||||
|
453: ForkJoinPool.commonPool-worker-3
|
||||||
|
454: ForkJoinPool.commonPool-worker-2
|
||||||
|
456: ForkJoinPool.commonPool-worker-2
|
||||||
|
455: ForkJoinPool.commonPool-worker-3
|
||||||
|
458: ForkJoinPool.commonPool-worker-3
|
||||||
|
457: ForkJoinPool.commonPool-worker-2
|
||||||
|
459: ForkJoinPool.commonPool-worker-3
|
||||||
|
460: ForkJoinPool.commonPool-worker-2
|
||||||
|
461: ForkJoinPool.commonPool-worker-3
|
||||||
|
462: ForkJoinPool.commonPool-worker-2
|
||||||
|
463: ForkJoinPool.commonPool-worker-3
|
||||||
|
464: ForkJoinPool.commonPool-worker-2
|
||||||
|
465: ForkJoinPool.commonPool-worker-3
|
||||||
|
466: ForkJoinPool.commonPool-worker-2
|
||||||
|
467: ForkJoinPool.commonPool-worker-3
|
||||||
|
468: ForkJoinPool.commonPool-worker-2
|
||||||
|
469: ForkJoinPool.commonPool-worker-3
|
||||||
|
470: ForkJoinPool.commonPool-worker-2
|
||||||
|
471: ForkJoinPool.commonPool-worker-3
|
||||||
|
472: ForkJoinPool.commonPool-worker-2
|
||||||
|
473: ForkJoinPool.commonPool-worker-3
|
||||||
|
474: ForkJoinPool.commonPool-worker-2
|
||||||
|
475: ForkJoinPool.commonPool-worker-3
|
||||||
|
476: ForkJoinPool.commonPool-worker-2
|
||||||
|
477: ForkJoinPool.commonPool-worker-3
|
||||||
|
478: ForkJoinPool.commonPool-worker-2
|
||||||
|
479: ForkJoinPool.commonPool-worker-3
|
||||||
|
480: ForkJoinPool.commonPool-worker-2
|
||||||
|
482: ForkJoinPool.commonPool-worker-2
|
||||||
|
481: ForkJoinPool.commonPool-worker-3
|
||||||
|
484: ForkJoinPool.commonPool-worker-3
|
||||||
|
484: ForkJoinPool.commonPool-worker-2
|
||||||
|
327: ForkJoinPool.commonPool-worker-1
|
||||||
|
485: ForkJoinPool.commonPool-worker-3
|
||||||
|
486: ForkJoinPool.commonPool-worker-2
|
||||||
|
488: ForkJoinPool.commonPool-worker-3
|
||||||
|
488: ForkJoinPool.commonPool-worker-1
|
||||||
|
489: ForkJoinPool.commonPool-worker-2
|
||||||
|
490: ForkJoinPool.commonPool-worker-3
|
||||||
|
491: ForkJoinPool.commonPool-worker-1
|
||||||
|
492: ForkJoinPool.commonPool-worker-2
|
||||||
|
495: ForkJoinPool.commonPool-worker-2
|
||||||
|
493: ForkJoinPool.commonPool-worker-3
|
||||||
|
496: ForkJoinPool.commonPool-worker-2
|
||||||
|
497: ForkJoinPool.commonPool-worker-3
|
||||||
|
499: ForkJoinPool.commonPool-worker-3
|
||||||
|
500: ForkJoinPool.commonPool-worker-3
|
||||||
|
501: ForkJoinPool.commonPool-worker-3
|
||||||
|
502: ForkJoinPool.commonPool-worker-3
|
||||||
|
503: ForkJoinPool.commonPool-worker-3
|
||||||
|
504: ForkJoinPool.commonPool-worker-3
|
||||||
|
505: ForkJoinPool.commonPool-worker-3
|
||||||
|
506: ForkJoinPool.commonPool-worker-3
|
||||||
|
507: ForkJoinPool.commonPool-worker-3
|
||||||
|
508: ForkJoinPool.commonPool-worker-3
|
||||||
|
509: ForkJoinPool.commonPool-worker-3
|
||||||
|
510: ForkJoinPool.commonPool-worker-3
|
||||||
|
511: ForkJoinPool.commonPool-worker-3
|
||||||
|
@ -26,7 +26,7 @@ class Mail {
|
|||||||
public String details() {
|
public String details() {
|
||||||
return toString() +
|
return toString() +
|
||||||
", General Delivery: " + generalDelivery +
|
", General Delivery: " + generalDelivery +
|
||||||
", Address Scanability: " + scannability +
|
", Address Scannability: " + scannability +
|
||||||
", Address Readability: " + readability +
|
", Address Readability: " + readability +
|
||||||
", Address Address: " + address +
|
", Address Address: " + address +
|
||||||
", Return address: " + returnAddress;
|
", Return address: " + returnAddress;
|
||||||
@ -138,52 +138,52 @@ public class PostOffice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output:
|
/* Output:
|
||||||
Mail 0, General Delivery: NO2, Address Scanability:
|
Mail 0, General Delivery: NO2, Address Scannability:
|
||||||
UNSCANNABLE, Address Readability: YES3, Address
|
UNSCANNABLE, Address Readability: YES3, Address
|
||||||
Address: OK1, Return address: OK1
|
Address: OK1, Return address: OK1
|
||||||
Delivering Mail 0 normally
|
Delivering Mail 0 normally
|
||||||
*****
|
*****
|
||||||
Mail 1, General Delivery: NO5, Address Scanability:
|
Mail 1, General Delivery: NO5, Address Scannability:
|
||||||
YES3, Address Readability: ILLEGIBLE, Address Address:
|
YES3, Address Readability: ILLEGIBLE, Address Address:
|
||||||
OK5, Return address: OK1
|
OK5, Return address: OK1
|
||||||
Delivering Mail 1 automatically
|
Delivering Mail 1 automatically
|
||||||
*****
|
*****
|
||||||
Mail 2, General Delivery: YES, Address Scanability:
|
Mail 2, General Delivery: YES, Address Scannability:
|
||||||
YES3, Address Readability: YES1, Address Address: OK1,
|
YES3, Address Readability: YES1, Address Address: OK1,
|
||||||
Return address: OK5
|
Return address: OK5
|
||||||
Using general delivery for Mail 2
|
Using general delivery for Mail 2
|
||||||
*****
|
*****
|
||||||
Mail 3, General Delivery: NO4, Address Scanability:
|
Mail 3, General Delivery: NO4, Address Scannability:
|
||||||
YES3, Address Readability: YES1, Address Address:
|
YES3, Address Readability: YES1, Address Address:
|
||||||
INCORRECT, Return address: OK4
|
INCORRECT, Return address: OK4
|
||||||
Returning Mail 3 to sender
|
Returning Mail 3 to sender
|
||||||
*****
|
*****
|
||||||
Mail 4, General Delivery: NO4, Address Scanability:
|
Mail 4, General Delivery: NO4, Address Scannability:
|
||||||
UNSCANNABLE, Address Readability: YES1, Address
|
UNSCANNABLE, Address Readability: YES1, Address
|
||||||
Address: INCORRECT, Return address: OK2
|
Address: INCORRECT, Return address: OK2
|
||||||
Returning Mail 4 to sender
|
Returning Mail 4 to sender
|
||||||
*****
|
*****
|
||||||
Mail 5, General Delivery: NO3, Address Scanability:
|
Mail 5, General Delivery: NO3, Address Scannability:
|
||||||
YES1, Address Readability: ILLEGIBLE, Address Address:
|
YES1, Address Readability: ILLEGIBLE, Address Address:
|
||||||
OK4, Return address: OK2
|
OK4, Return address: OK2
|
||||||
Delivering Mail 5 automatically
|
Delivering Mail 5 automatically
|
||||||
*****
|
*****
|
||||||
Mail 6, General Delivery: YES, Address Scanability:
|
Mail 6, General Delivery: YES, Address Scannability:
|
||||||
YES4, Address Readability: ILLEGIBLE, Address Address:
|
YES4, Address Readability: ILLEGIBLE, Address Address:
|
||||||
OK4, Return address: OK4
|
OK4, Return address: OK4
|
||||||
Using general delivery for Mail 6
|
Using general delivery for Mail 6
|
||||||
*****
|
*****
|
||||||
Mail 7, General Delivery: YES, Address Scanability:
|
Mail 7, General Delivery: YES, Address Scannability:
|
||||||
YES3, Address Readability: YES4, Address Address: OK2,
|
YES3, Address Readability: YES4, Address Address: OK2,
|
||||||
Return address: MISSING
|
Return address: MISSING
|
||||||
Using general delivery for Mail 7
|
Using general delivery for Mail 7
|
||||||
*****
|
*****
|
||||||
Mail 8, General Delivery: NO3, Address Scanability:
|
Mail 8, General Delivery: NO3, Address Scannability:
|
||||||
YES1, Address Readability: YES3, Address Address:
|
YES1, Address Readability: YES3, Address Address:
|
||||||
INCORRECT, Return address: MISSING
|
INCORRECT, Return address: MISSING
|
||||||
Mail 8 is a dead letter
|
Mail 8 is a dead letter
|
||||||
*****
|
*****
|
||||||
Mail 9, General Delivery: NO1, Address Scanability:
|
Mail 9, General Delivery: NO1, Address Scannability:
|
||||||
UNSCANNABLE, Address Readability: YES2, Address
|
UNSCANNABLE, Address Readability: YES2, Address
|
||||||
Address: OK1, Return address: OK4
|
Address: OK1, Return address: OK4
|
||||||
Delivering Mail 9 normally
|
Delivering Mail 9 normally
|
||||||
|
@ -11,7 +11,7 @@ public interface Food {
|
|||||||
}
|
}
|
||||||
enum MainCourse implements Food {
|
enum MainCourse implements Food {
|
||||||
LASAGNE, BURRITO, PAD_THAI,
|
LASAGNE, BURRITO, PAD_THAI,
|
||||||
LENTILS, HUMMOUS, VINDALOO;
|
LENTILS, HUMMUS, VINDALOO;
|
||||||
}
|
}
|
||||||
enum Dessert implements Food {
|
enum Dessert implements Food {
|
||||||
TIRAMISU, GELATO, BLACK_FOREST_CAKE,
|
TIRAMISU, GELATO, BLACK_FOREST_CAKE,
|
||||||
|
@ -21,7 +21,7 @@ public enum Meal2 {
|
|||||||
}
|
}
|
||||||
enum MainCourse implements Food {
|
enum MainCourse implements Food {
|
||||||
LASAGNE, BURRITO, PAD_THAI,
|
LASAGNE, BURRITO, PAD_THAI,
|
||||||
LENTILS, HUMMOUS, VINDALOO;
|
LENTILS, HUMMUS, VINDALOO;
|
||||||
}
|
}
|
||||||
enum Dessert implements Food {
|
enum Dessert implements Food {
|
||||||
TIRAMISU, GELATO, BLACK_FOREST_CAKE,
|
TIRAMISU, GELATO, BLACK_FOREST_CAKE,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
import collections.MapOfList;
|
import collections.MapOfList;
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class IndividualTest {
|
public class IndividualTest {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Using Collection.checkedList()
|
// Using Collection.checkedList()
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class CheckedList {
|
public class CheckedList {
|
||||||
@ -30,6 +30,6 @@ public class CheckedList {
|
|||||||
}
|
}
|
||||||
/* Output:
|
/* Output:
|
||||||
Expected: java.lang.ClassCastException: Attempt to
|
Expected: java.lang.ClassCastException: Attempt to
|
||||||
insert class typeinfo.pets.Cat element into collection
|
insert class reflection.pets.Cat element into collection
|
||||||
with element type class typeinfo.pets.Dog
|
with element type class reflection.pets.Dog
|
||||||
*/
|
*/
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// "Assisted Latent Typing"
|
// "Assisted Latent Typing"
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
import java.util.function.*;
|
import java.util.function.*;
|
||||||
|
|
||||||
class PerformingDogA extends Dog {
|
class PerformingDogA extends Dog {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// No (direct) latent typing in Java
|
// No (direct) latent typing in Java
|
||||||
import typeinfo.pets.*;
|
import reflection.pets.*;
|
||||||
|
|
||||||
class PerformingDog extends Dog implements Performs {
|
class PerformingDog extends Dog implements Performs {
|
||||||
@Override
|
@Override
|
||||||
|
@ -10,7 +10,7 @@ public class GenericHolder<T> {
|
|||||||
public T get() { return a; }
|
public T get() { return a; }
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
GenericHolder<Automobile> h3 =
|
GenericHolder<Automobile> h3 =
|
||||||
new GenericHolder<Automobile>();
|
new GenericHolder<>();
|
||||||
h3.set(new Automobile()); // type checked
|
h3.set(new Automobile()); // type checked
|
||||||
Automobile a = h3.get(); // No cast needed
|
Automobile a = h3.get(); // No cast needed
|
||||||
//- h3.set("Not an Automobile"); // Error
|
//- h3.set("Not an Automobile"); // Error
|
||||||
|
@ -6,7 +6,7 @@ project(':validating') {
|
|||||||
|
|
||||||
project(':equalshashcode') {
|
project(':equalshashcode') {
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':typeinfo')
|
compile project(':reflection')
|
||||||
compile project(':collections')
|
compile project(':collections')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,13 +48,13 @@ project(':hiding') {
|
|||||||
|
|
||||||
project(':generics') {
|
project(':generics') {
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':typeinfo')
|
compile project(':reflection')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project(':collections') {
|
project(':collections') {
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':typeinfo')
|
compile project(':reflection')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ public class Flower {
|
|||||||
}
|
}
|
||||||
Flower() {
|
Flower() {
|
||||||
this("hi", 47);
|
this("hi", 47);
|
||||||
System.out.println("no-arg constructor");
|
System.out.println("Zero-argument constructor");
|
||||||
}
|
}
|
||||||
void printPetalCount() {
|
void printPetalCount() {
|
||||||
//- this(11); // Not inside non-constructor!
|
//- this(11); // Not inside non-constructor!
|
||||||
@ -41,6 +41,6 @@ public class Flower {
|
|||||||
/* Output:
|
/* Output:
|
||||||
Constructor w/ int arg only, petalCount= 47
|
Constructor w/ int arg only, petalCount= 47
|
||||||
String & int args
|
String & int args
|
||||||
no-arg constructor
|
Zero-argument constructor
|
||||||
petalCount = 47 s = hi
|
petalCount = 47 s = hi
|
||||||
*/
|
*/
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Overloading based on the order of the arguments
|
// Overloading based on parameter order
|
||||||
|
|
||||||
public class OverloadingOrder {
|
public class OverloadingOrder {
|
||||||
static void f(String s, int i) {
|
static void f(String s, int i) {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Constructors can have arguments
|
// Constructors can have parameters
|
||||||
|
|
||||||
class Rock2 {
|
class Rock2 {
|
||||||
Rock2(int i) {
|
Rock2(int i) {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
|
|
||||||
/** You can <em>even</em> insert a list:
|
/** You can <em>even</em> insert a list:
|
||||||
* <ol>
|
* <ol>
|
||||||
* <li> Item one
|
* <li> Item one
|
||||||
@ -9,4 +10,5 @@
|
|||||||
* <li> Item three
|
* <li> Item three
|
||||||
* </ol>
|
* </ol>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Documentation3 {}
|
public class Documentation3 {}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Supplier from a class with a no-arg constructor
|
// Supplier from a class with a zero-argument constructor
|
||||||
package onjava;
|
package onjava;
|
||||||
import java.util.function.*;
|
import java.util.function.*;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
@ -130,7 +130,7 @@ public class Countries {
|
|||||||
{"MOLDOVA","Chisinau"},
|
{"MOLDOVA","Chisinau"},
|
||||||
{"RUSSIA","Moscow"},
|
{"RUSSIA","Moscow"},
|
||||||
{"TAJIKISTAN","Dushanbe"},
|
{"TAJIKISTAN","Dushanbe"},
|
||||||
{"TURKMENISTAN","Ashkabad"},
|
{"TURKMENISTAN","Ashkhabad"},
|
||||||
{"UKRAINE","Kyiv"},
|
{"UKRAINE","Kyiv"},
|
||||||
{"UZBEKISTAN","Tashkent"},
|
{"UZBEKISTAN","Tashkent"},
|
||||||
// Europe
|
// Europe
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Helper interface to allow lambda expressions
|
// Helper interface to allow lambda expressions.
|
||||||
package onjava;
|
package onjava;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
|
|
||||||
|
@ -63,11 +63,11 @@ public class AtUnit implements ProcessFiles.Strategy {
|
|||||||
.getDeclaredConstructor()
|
.getDeclaredConstructor()
|
||||||
.getModifiers())) {
|
.getModifiers())) {
|
||||||
System.out.println("Error: " + testClass +
|
System.out.println("Error: " + testClass +
|
||||||
" no-arg constructor must be public");
|
" zero-argument constructor must be public");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
} catch(NoSuchMethodException e) {
|
} catch(NoSuchMethodException e) {
|
||||||
// Synthesized no-arg constructor; OK
|
// Synthesized zero-argument constructor; OK
|
||||||
}
|
}
|
||||||
System.out.println(testClass.getName());
|
System.out.println(testClass.getName());
|
||||||
}
|
}
|
||||||
@ -159,7 +159,7 @@ public class AtUnit implements ProcessFiles.Strategy {
|
|||||||
throw new RuntimeException("Couldn't run " +
|
throw new RuntimeException("Couldn't run " +
|
||||||
"@TestObject (creator) method.");
|
"@TestObject (creator) method.");
|
||||||
}
|
}
|
||||||
} else { // Use the no-arg constructor:
|
} else { // Use the zero-argument constructor:
|
||||||
try {
|
try {
|
||||||
return testClass
|
return testClass
|
||||||
.getConstructor().newInstance();
|
.getConstructor().newInstance();
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Demonstration of Observer pattern using
|
// Demonstration of the Observer pattern using
|
||||||
// Java's built-in observer classes.
|
// Java's built-in observer classes.
|
||||||
// {ExcludeFromGradle} // Won't work under WSL2
|
// {ExcludeFromGradle} // Won't work under WSL2
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
@ -12,46 +12,34 @@ import java.util.*;
|
|||||||
import onjava.*;
|
import onjava.*;
|
||||||
import onjava.MouseClick;
|
import onjava.MouseClick;
|
||||||
|
|
||||||
// You must inherit a new type of Observable:
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
class BoxObservable extends Observable {
|
class Boxes extends JFrame {
|
||||||
@Override
|
Observable notifier = new Observable() {
|
||||||
public void notifyObservers(Object b) {
|
@Override
|
||||||
// Otherwise it won't propagate changes:
|
public void notifyObservers(Object b) {
|
||||||
setChanged();
|
setChanged();
|
||||||
super.notifyObservers(b);
|
super.notifyObservers(b);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
public Boxes(int grid) {
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class BoxObserver extends JFrame {
|
|
||||||
Observable notifier = new BoxObservable();
|
|
||||||
public BoxObserver(int grid) {
|
|
||||||
setTitle("Demonstrates Observer pattern");
|
setTitle("Demonstrates Observer pattern");
|
||||||
Container cp = getContentPane();
|
Container cp = getContentPane();
|
||||||
cp.setLayout(new GridLayout(grid, grid));
|
cp.setLayout(new GridLayout(grid, grid));
|
||||||
for(int x = 0; x < grid; x++)
|
for(int x = 0; x < grid; x++)
|
||||||
for(int y = 0; y < grid; y++)
|
for(int y = 0; y < grid; y++)
|
||||||
cp.add(new OCBox(x, y, notifier));
|
cp.add(new Box(x, y, notifier));
|
||||||
}
|
setSize(500, 400);
|
||||||
public static void main(String[] args) {
|
setVisible(true);
|
||||||
// For automated test runs:
|
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||||
// new TimedAbort(4);
|
|
||||||
int grid = 8;
|
|
||||||
if(args.length > 0)
|
|
||||||
grid = Integer.parseInt(args[0]);
|
|
||||||
JFrame f = new BoxObserver(grid);
|
|
||||||
f.setSize(500, 400);
|
|
||||||
f.setVisible(true);
|
|
||||||
f.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
class OCBox extends JPanel implements Observer {
|
class Box extends JPanel implements Observer {
|
||||||
Observable notifier;
|
int x, y; // Location in grid
|
||||||
int x, y; // Locations in grid
|
Color color = COLORS[
|
||||||
Color cColor = newColor();
|
(int)(Math.random() * COLORS.length)
|
||||||
|
];
|
||||||
static final Color[] COLORS = {
|
static final Color[] COLORS = {
|
||||||
Color.black, Color.blue, Color.cyan,
|
Color.black, Color.blue, Color.cyan,
|
||||||
Color.darkGray, Color.gray, Color.green,
|
Color.darkGray, Color.gray, Color.green,
|
||||||
@ -59,35 +47,38 @@ class OCBox extends JPanel implements Observer {
|
|||||||
Color.orange, Color.pink, Color.red,
|
Color.orange, Color.pink, Color.red,
|
||||||
Color.white, Color.yellow
|
Color.white, Color.yellow
|
||||||
};
|
};
|
||||||
static Color newColor() {
|
Box(int x, int y, Observable notifier) {
|
||||||
return COLORS[
|
|
||||||
(int)(Math.random() * COLORS.length)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
OCBox(int x, int y, Observable notifier) {
|
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
notifier.addObserver(this);
|
notifier.addObserver(this);
|
||||||
this.notifier = notifier;
|
|
||||||
addMouseListener((MouseClick)
|
addMouseListener((MouseClick)
|
||||||
e -> notifier.notifyObservers(OCBox.this));
|
e -> notifier.notifyObservers(Box.this));
|
||||||
}
|
}
|
||||||
@Override public void paintComponent(Graphics g) {
|
@Override public void paintComponent(Graphics g) {
|
||||||
super.paintComponent(g);
|
super.paintComponent(g);
|
||||||
g.setColor(cColor);
|
g.setColor(color);
|
||||||
Dimension s = getSize();
|
Dimension s = getSize();
|
||||||
g.fillRect(0, 0, s.width, s.height);
|
g.fillRect(0, 0, s.width, s.height);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void update(Observable o, Object arg) {
|
public void update(Observable o, Object arg) {
|
||||||
OCBox clicked = (OCBox)arg;
|
Box clicked = (Box)arg;
|
||||||
if(nextTo(clicked)) {
|
if(nextTo(clicked)) {
|
||||||
cColor = clicked.cColor;
|
color = clicked.color;
|
||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private boolean nextTo(OCBox b) {
|
private boolean nextTo(Box b) {
|
||||||
return Math.abs(x - b.x) <= 1 &&
|
return Math.abs(x - b.x) <= 1 &&
|
||||||
Math.abs(y - b.y) <= 1;
|
Math.abs(y - b.y) <= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BoxObserver {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int grid = 8;
|
||||||
|
if(args.length > 0)
|
||||||
|
grid = Integer.parseInt(args[0]);
|
||||||
|
new Boxes(grid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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.
|
// Visit http://OnJava8.com for more book information.
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
class Command {
|
||||||
|
public final String msg;
|
||||||
|
public Command(String msg) {
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class CommandPattern {
|
public class CommandPattern {
|
||||||
|
public static void show(Command cmd) {
|
||||||
|
System.out.println(cmd.msg);
|
||||||
|
}
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
List<Runnable> macro = Arrays.asList(
|
show(new Command("First Command"));
|
||||||
() -> System.out.print("Hello "),
|
show(new Command("Second Command"));
|
||||||
() -> System.out.print("World! "),
|
|
||||||
() -> System.out.print("I'm the command pattern!")
|
|
||||||
);
|
|
||||||
macro.forEach(Runnable::run);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output:
|
/* Output:
|
||||||
Hello World! I'm the command pattern!
|
First Command
|
||||||
|
Second Command
|
||||||
*/
|
*/
|
||||||
|
25
patterns/Macro.java
Normal file
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
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Demonstration of multiple dispatching
|
// Demonstration of multiple dispatching.
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.*;
|
import java.util.function.*;
|
||||||
import java.util.stream.*;
|
import java.util.stream.*;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Simple demonstration of the Proxy pattern
|
// Basic demonstration of the Proxy pattern.
|
||||||
|
|
||||||
interface ProxyBase {
|
interface ProxyBase {
|
||||||
void f();
|
void f();
|
||||||
@ -11,10 +11,8 @@ interface ProxyBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Proxy implements ProxyBase {
|
class Proxy implements ProxyBase {
|
||||||
private ProxyBase implementation;
|
private ProxyBase implementation =
|
||||||
Proxy() {
|
new Implementation();
|
||||||
implementation = new Implementation();
|
|
||||||
}
|
|
||||||
// Pass method calls to the implementation:
|
// Pass method calls to the implementation:
|
||||||
@Override
|
@Override
|
||||||
public void f() { implementation.f(); }
|
public void f() { implementation.f(); }
|
||||||
|
9
patterns/Resource.java
Normal file
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
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// A simple static factory method
|
// A basic static factory method.
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.*;
|
import java.util.stream.*;
|
||||||
import patterns.shapes.*;
|
import patterns.shapes.*;
|
||||||
|
@ -8,9 +8,9 @@ import java.util.stream.*;
|
|||||||
import patterns.shapes.*;
|
import patterns.shapes.*;
|
||||||
|
|
||||||
public class ShapeFactory2 implements FactoryMethod {
|
public class ShapeFactory2 implements FactoryMethod {
|
||||||
Map<String, Constructor> factories =
|
private Map<String, Constructor> factories =
|
||||||
new HashMap<>();
|
new HashMap<>();
|
||||||
static Constructor load(String id) {
|
private static Constructor load(String id) {
|
||||||
System.out.println("loading " + id);
|
System.out.println("loading " + id);
|
||||||
try {
|
try {
|
||||||
return Class.forName("patterns.shapes." + id)
|
return Class.forName("patterns.shapes." + id)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Polymorphic factory methods
|
// Polymorphic factory methods.
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.*;
|
import java.util.function.*;
|
||||||
import java.util.stream.*;
|
import java.util.stream.*;
|
||||||
@ -19,14 +19,15 @@ class RandomShapes implements Supplier<Shape> {
|
|||||||
this.factories = factories;
|
this.factories = factories;
|
||||||
}
|
}
|
||||||
@Override public Shape get() {
|
@Override public Shape get() {
|
||||||
return factories[
|
return
|
||||||
rand.nextInt(factories.length)].create();
|
factories[rand.nextInt(factories.length)]
|
||||||
|
.create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ShapeFactory3 {
|
public class ShapeFactory3 {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
RandomShapes rs = new RandomShapes(
|
RandomShapes rs = new RandomShapes( // [1]
|
||||||
Circle::new, Square::new, Triangle::new
|
Circle::new, Square::new, Triangle::new
|
||||||
);
|
);
|
||||||
Stream.generate(rs)
|
Stream.generate(rs)
|
||||||
|
18
patterns/Single.java
Normal file
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.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
|
|
||||||
interface Resource {
|
final class IntegerSingleton
|
||||||
int getValue();
|
implements Resource<Integer> {
|
||||||
void setValue(int x);
|
private static IntegerSingleton value =
|
||||||
}
|
new IntegerSingleton();
|
||||||
|
private Integer i = Integer.valueOf(0);
|
||||||
// This isn't inherited from a Cloneable
|
private IntegerSingleton() {
|
||||||
// base class and cloneability isn't added so
|
System.out.println("IntegerSingleton()");
|
||||||
// making it final prevents cloneability from
|
|
||||||
// being added through inheritance. This also
|
|
||||||
// implements thread-safe lazy initialization:
|
|
||||||
|
|
||||||
final class Singleton {
|
|
||||||
private static final class
|
|
||||||
ResourceImpl implements Resource {
|
|
||||||
private int i;
|
|
||||||
private ResourceImpl(int i) {
|
|
||||||
this.i = i;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public synchronized int getValue() {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public synchronized void setValue(int x) {
|
|
||||||
i = x;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private static class ResourceHolder {
|
public static IntegerSingleton instance() {
|
||||||
private static Resource resource =
|
return value;
|
||||||
new ResourceImpl(47);
|
|
||||||
}
|
|
||||||
public static Resource getResource() {
|
|
||||||
return ResourceHolder.resource;
|
|
||||||
}
|
}
|
||||||
|
@Override public synchronized
|
||||||
|
Integer get() { return i; }
|
||||||
|
@Override public synchronized
|
||||||
|
void set(Integer x) { i = x; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SingletonPattern {
|
public class SingletonPattern {
|
||||||
|
public static <T> void show(Resource<T> r) {
|
||||||
|
T val = r.get();
|
||||||
|
System.out.println(val);
|
||||||
|
}
|
||||||
|
public static <T> void put(Resource<T> r, T val) {
|
||||||
|
r.set(val);
|
||||||
|
}
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Resource r = Singleton.getResource();
|
System.out.println("Inside main()");
|
||||||
System.out.println(r.getValue());
|
Resource<Integer> ir =
|
||||||
Resource s2 = Singleton.getResource();
|
IntegerSingleton.instance();
|
||||||
s2.setValue(9);
|
Resource<Integer> ir2 =
|
||||||
System.out.println(r.getValue());
|
IntegerSingleton.instance();
|
||||||
try {
|
show(ir);
|
||||||
// Can't do this: compile-time error.
|
put(ir2, Integer.valueOf(9));
|
||||||
// Singleton s3 = (Singleton)s2.clone();
|
show(ir);
|
||||||
} catch(Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output:
|
/* Output:
|
||||||
47
|
Inside main()
|
||||||
|
IntegerSingleton()
|
||||||
|
0
|
||||||
9
|
9
|
||||||
*/
|
*/
|
||||||
|
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
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Simple demonstration of the State pattern
|
// Basic demonstration of the State pattern.
|
||||||
|
|
||||||
interface StateBase {
|
class State {
|
||||||
void f();
|
private State implementation;
|
||||||
void g();
|
protected State() {}
|
||||||
void h();
|
public State(State imp) {
|
||||||
void changeImp(StateBase newImp);
|
|
||||||
}
|
|
||||||
|
|
||||||
class State implements StateBase {
|
|
||||||
private StateBase implementation;
|
|
||||||
State(StateBase imp) {
|
|
||||||
implementation = imp;
|
implementation = imp;
|
||||||
}
|
}
|
||||||
@Override
|
public void change(State newImp) {
|
||||||
public void changeImp(StateBase newImp) {
|
|
||||||
implementation = newImp;
|
implementation = newImp;
|
||||||
}
|
}
|
||||||
// Pass method calls to the implementation:
|
// Forward method calls to the implementation:
|
||||||
@Override
|
|
||||||
public void f() { implementation.f(); }
|
public void f() { implementation.f(); }
|
||||||
@Override
|
|
||||||
public void g() { implementation.g(); }
|
public void g() { implementation.g(); }
|
||||||
@Override
|
|
||||||
public void h() { implementation.h(); }
|
public void h() { implementation.h(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
class Implementation1 implements StateBase {
|
class Implementation1 extends State {
|
||||||
@Override public void f() {
|
@Override public void f() {
|
||||||
System.out.println("Implementation1.f()");
|
System.out.println("Implementation1.f()");
|
||||||
}
|
}
|
||||||
@ -39,11 +29,9 @@ class Implementation1 implements StateBase {
|
|||||||
@Override public void h() {
|
@Override public void h() {
|
||||||
System.out.println("Implementation1.h()");
|
System.out.println("Implementation1.h()");
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public void changeImp(StateBase newImp) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Implementation2 implements StateBase {
|
class Implementation2 extends State {
|
||||||
@Override public void f() {
|
@Override public void f() {
|
||||||
System.out.println("Implementation2.f()");
|
System.out.println("Implementation2.f()");
|
||||||
}
|
}
|
||||||
@ -53,28 +41,27 @@ class Implementation2 implements StateBase {
|
|||||||
@Override public void h() {
|
@Override public void h() {
|
||||||
System.out.println("Implementation2.h()");
|
System.out.println("Implementation2.h()");
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public void changeImp(StateBase newImp) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StateDemo {
|
public class StateDemo {
|
||||||
static void test(StateBase b) {
|
static void test(State s) {
|
||||||
b.f();
|
s.f();
|
||||||
b.g();
|
s.g();
|
||||||
b.h();
|
s.h();
|
||||||
}
|
}
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
StateBase b =
|
State s = new State(new Implementation1());
|
||||||
new State(new Implementation1());
|
test(s);
|
||||||
test(b);
|
System.out.println("Changing implementation");
|
||||||
b.changeImp(new Implementation2());
|
s.change(new Implementation2());
|
||||||
test(b);
|
test(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output:
|
/* Output:
|
||||||
Implementation1.f()
|
Implementation1.f()
|
||||||
Implementation1.g()
|
Implementation1.g()
|
||||||
Implementation1.h()
|
Implementation1.h()
|
||||||
|
Changing implementation
|
||||||
Implementation2.f()
|
Implementation2.f()
|
||||||
Implementation2.g()
|
Implementation2.g()
|
||||||
Implementation2.h()
|
Implementation2.h()
|
||||||
|
@ -2,29 +2,29 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Simple demonstration of Template Method
|
// Basic Template Method pattern.
|
||||||
import java.util.stream.*;
|
import java.util.stream.*;
|
||||||
|
|
||||||
abstract class ApplicationFramework {
|
abstract class ApplicationFramework {
|
||||||
ApplicationFramework() {
|
ApplicationFramework() {
|
||||||
templateMethod();
|
templateMethod();
|
||||||
}
|
}
|
||||||
abstract void customize1();
|
abstract void customize1(int n);
|
||||||
abstract void customize2();
|
abstract void customize2(int n);
|
||||||
// "private" means automatically "final":
|
// "private" means automatically "final":
|
||||||
private void templateMethod() {
|
private void templateMethod() {
|
||||||
IntStream.range(0, 5).forEach(
|
IntStream.range(0, 5).forEach(
|
||||||
n -> { customize1(); customize2(); });
|
n -> { customize1(n); customize2(n); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new "application":
|
// Create a new application:
|
||||||
class MyApp extends ApplicationFramework {
|
class MyApp extends ApplicationFramework {
|
||||||
@Override void customize1() {
|
@Override void customize1(int n) {
|
||||||
System.out.print("Hello ");
|
System.out.print("customize1 " + n);
|
||||||
}
|
}
|
||||||
@Override void customize2() {
|
@Override void customize2(int n) {
|
||||||
System.out.println("World!");
|
System.out.println(" customize2 " + n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,9 +34,9 @@ public class TemplateMethod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output:
|
/* Output:
|
||||||
Hello World!
|
customize1 0 customize2 0
|
||||||
Hello World!
|
customize1 1 customize2 1
|
||||||
Hello World!
|
customize1 2 customize2 2
|
||||||
Hello World!
|
customize1 3 customize2 3
|
||||||
Hello World!
|
customize1 4 customize2 4
|
||||||
*/
|
*/
|
||||||
|
20
patterns/TestSingle.java
Normal file
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
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// An example of the Abstract Factory pattern
|
// An example of the Abstract Factory pattern.
|
||||||
// {java patterns.abstractfactory.GameEnvironment}
|
// {java patterns.abstractfactory.GameEnvironment}
|
||||||
package patterns.abstractfactory;
|
package patterns.abstractfactory;
|
||||||
import java.util.function.*;
|
import java.util.function.*;
|
||||||
@ -23,10 +23,10 @@ class Kitty implements Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class KungFuGuy implements Player {
|
class Fighter implements Player {
|
||||||
@Override
|
@Override
|
||||||
public void interactWith(Obstacle ob) {
|
public void interactWith(Obstacle ob) {
|
||||||
System.out.print("KungFuGuy now battles a ");
|
System.out.print("Fighter now battles a ");
|
||||||
ob.action();
|
ob.action();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,9 +37,9 @@ class Puzzle implements Obstacle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NastyWeapon implements Obstacle {
|
class Weapon implements Obstacle {
|
||||||
@Override public void action() {
|
@Override public void action() {
|
||||||
System.out.println("NastyWeapon");
|
System.out.println("Weapon");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,11 +58,11 @@ extends GameElementFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class KillAndDismember
|
class Melee
|
||||||
extends GameElementFactory {
|
extends GameElementFactory {
|
||||||
KillAndDismember() {
|
Melee() {
|
||||||
player = KungFuGuy::new;
|
player = Fighter::new;
|
||||||
obstacle = NastyWeapon::new;
|
obstacle = Weapon::new;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,15 +80,15 @@ public class GameEnvironment {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
GameElementFactory
|
GameElementFactory
|
||||||
kp = new KittiesAndPuzzles(),
|
kp = new KittiesAndPuzzles(),
|
||||||
kd = new KillAndDismember();
|
ml = new Melee();
|
||||||
GameEnvironment
|
GameEnvironment
|
||||||
g1 = new GameEnvironment(kp),
|
g1 = new GameEnvironment(kp),
|
||||||
g2 = new GameEnvironment(kd);
|
g2 = new GameEnvironment(ml);
|
||||||
g1.play();
|
g1.play();
|
||||||
g2.play();
|
g2.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output:
|
/* Output:
|
||||||
Kitty has encountered a Puzzle
|
Kitty has encountered a Puzzle
|
||||||
KungFuGuy now battles a NastyWeapon
|
Fighter now battles a Weapon
|
||||||
*/
|
*/
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Variations on the Adapter pattern
|
// Variations on the Adapter pattern.
|
||||||
// {java patterns.adapt.Adapter}
|
// {java patterns.adapt.Adapter}
|
||||||
package patterns.adapt;
|
package patterns.adapt;
|
||||||
|
|
||||||
|
@ -2,55 +2,32 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Using the Functional interface
|
|
||||||
// {java patterns.chain.ChainOfResponsibility}
|
// {java patterns.chain.ChainOfResponsibility}
|
||||||
package patterns.chain;
|
package patterns.chain;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.*;
|
import java.util.function.*;
|
||||||
|
|
||||||
class Result {
|
|
||||||
boolean success;
|
|
||||||
List<Double> line;
|
|
||||||
Result(List<Double> data) {
|
|
||||||
success = true;
|
|
||||||
line = data;
|
|
||||||
}
|
|
||||||
Result() {
|
|
||||||
success = false;
|
|
||||||
line = Collections.<Double>emptyList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Fail extends Result {}
|
|
||||||
|
|
||||||
interface Algorithm {
|
interface Algorithm {
|
||||||
Result algorithm(List<Double> line);
|
Result algorithm(List<Double> line);
|
||||||
}
|
}
|
||||||
|
|
||||||
class FindMinima {
|
class FindMinima {
|
||||||
public static Result leastSquares(List<Double> line) {
|
public static Result test(
|
||||||
System.out.println("LeastSquares.algorithm");
|
boolean success, String id, double d1, double d2) {
|
||||||
boolean weSucceed = false;
|
System.out.println(id);
|
||||||
if(weSucceed) // Actual test/calculation here
|
if(success) // Actual test/calculation here
|
||||||
return new Result(Arrays.asList(1.1, 2.2));
|
return new Result(Arrays.asList(d1, d2));
|
||||||
else // Try the next one in the chain:
|
else // Try the next one in the chain:
|
||||||
return new Fail();
|
return Result.fail;
|
||||||
|
}
|
||||||
|
public static Result leastSquares(List<Double> line) {
|
||||||
|
return test(false, "LeastSquares", 1.1, 2.2);
|
||||||
}
|
}
|
||||||
public static Result perturbation(List<Double> line) {
|
public static Result perturbation(List<Double> line) {
|
||||||
System.out.println("Perturbation.algorithm");
|
return test(false, "Perturbation", 3.3, 4.4);
|
||||||
boolean weSucceed = false;
|
|
||||||
if(weSucceed) // Actual test/calculation here
|
|
||||||
return new Result(Arrays.asList(3.3, 4.4));
|
|
||||||
else
|
|
||||||
return new Fail();
|
|
||||||
}
|
}
|
||||||
public static Result bisection(List<Double> line) {
|
public static Result bisection(List<Double> line) {
|
||||||
System.out.println("Bisection.algorithm");
|
return test(true, "Bisection", 5.5, 6.6);
|
||||||
boolean weSucceed = true;
|
|
||||||
if(weSucceed) // Actual test/calculation here
|
|
||||||
return new Result(Arrays.asList(5.5, 6.6));
|
|
||||||
else
|
|
||||||
return new Fail();
|
|
||||||
}
|
}
|
||||||
static List<Function<List<Double>, Result>>
|
static List<Function<List<Double>, Result>>
|
||||||
algorithms = Arrays.asList(
|
algorithms = Arrays.asList(
|
||||||
@ -65,7 +42,7 @@ class FindMinima {
|
|||||||
if(result.success)
|
if(result.success)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return new Fail();
|
return Result.fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,8 +60,8 @@ public class ChainOfResponsibility {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output:
|
/* Output:
|
||||||
LeastSquares.algorithm
|
LeastSquares
|
||||||
Perturbation.algorithm
|
Perturbation
|
||||||
Bisection.algorithm
|
Bisection
|
||||||
[5.5, 6.6]
|
[5.5, 6.6]
|
||||||
*/
|
*/
|
||||||
|
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,13 +2,13 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Aluminum for double dispatching
|
// Aluminum with double dispatching.
|
||||||
package patterns.doubledispatch;
|
package patterns.doubledispatch;
|
||||||
import patterns.trash.*;
|
import patterns.trash.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Aluminum extends patterns.trash.Aluminum
|
public class Aluminum extends patterns.trash.Aluminum
|
||||||
implements TypedBinMember {
|
implements TypedBinMember {
|
||||||
public Aluminum(double wt) { super(wt); }
|
public Aluminum(double wt) { super(wt); }
|
||||||
@Override
|
@Override
|
||||||
public boolean addToBin(List<TypedBin> tbins) {
|
public boolean addToBin(List<TypedBin> tbins) {
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Cardboard for double dispatching
|
// Cardboard with double dispatching.
|
||||||
package patterns.doubledispatch;
|
package patterns.doubledispatch;
|
||||||
import patterns.trash.*;
|
import patterns.trash.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Cardboard extends patterns.trash.Cardboard
|
public class Cardboard extends patterns.trash.Cardboard
|
||||||
implements TypedBinMember {
|
implements TypedBinMember {
|
||||||
public Cardboard(double wt) { super(wt); }
|
public Cardboard(double wt) { super(wt); }
|
||||||
@Override
|
@Override
|
||||||
public boolean addToBin(List<TypedBin> tbins) {
|
public boolean addToBin(List<TypedBin> tbins) {
|
||||||
|
@ -3,90 +3,104 @@
|
|||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Using multiple dispatching to handle more
|
// Using multiple dispatching to handle more
|
||||||
// than one unknown type during a method call
|
// than one unknown type during a method call.
|
||||||
// {java patterns.doubledispatch.DoubleDispatch}
|
// {java patterns.doubledispatch.DoubleDispatch}
|
||||||
package patterns.doubledispatch;
|
package patterns.doubledispatch;
|
||||||
import patterns.trash.*;
|
import patterns.trash.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
class AluminumBin extends TypedBin {
|
class AluminumBin extends TypedBin {
|
||||||
|
public AluminumBin() { super("Aluminum"); }
|
||||||
@Override public boolean add(Aluminum a) {
|
@Override public boolean add(Aluminum a) {
|
||||||
return addIt(a);
|
return addIt(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PaperBin extends TypedBin {
|
class PaperBin extends TypedBin {
|
||||||
|
public PaperBin() { super("Paper"); }
|
||||||
@Override public boolean add(Paper a) {
|
@Override public boolean add(Paper a) {
|
||||||
return addIt(a);
|
return addIt(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GlassBin extends TypedBin {
|
class GlassBin extends TypedBin {
|
||||||
|
public GlassBin() { super("Glass"); }
|
||||||
@Override public boolean add(Glass a) {
|
@Override public boolean add(Glass a) {
|
||||||
return addIt(a);
|
return addIt(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CardboardBin extends TypedBin {
|
class CardboardBin extends TypedBin {
|
||||||
|
public CardboardBin() { super("Cardboard"); }
|
||||||
@Override public boolean add(Cardboard a) {
|
@Override public boolean add(Cardboard a) {
|
||||||
return addIt(a);
|
return addIt(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TrashBinSet {
|
class TrashBinSet {
|
||||||
private List<TypedBin> binSet = Arrays.asList(
|
public final List<TypedBin> binSet =
|
||||||
new AluminumBin(),
|
Arrays.asList(
|
||||||
new PaperBin(),
|
new AluminumBin(), new PaperBin(),
|
||||||
new GlassBin(),
|
new GlassBin(), new CardboardBin()
|
||||||
new CardboardBin()
|
);
|
||||||
);
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void sortIntoBins(List bin) {
|
public void sortIntoBins(List bin) {
|
||||||
bin.forEach( aBin -> {
|
bin.forEach( aBin -> {
|
||||||
TypedBinMember t = (TypedBinMember)aBin;
|
TypedBinMember t = (TypedBinMember)aBin;
|
||||||
if(!t.addToBin(binSet))
|
if(!t.addToBin(binSet))
|
||||||
System.err.println("Couldn't add " + t);
|
throw new RuntimeException(
|
||||||
|
"sortIntoBins() couldn't add " + t);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public List<TypedBin> binSet() { return binSet; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DoubleDispatch {
|
public class DoubleDispatch {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
List<Trash> bin = new ArrayList<>();
|
List<Trash> bin = new ArrayList<>();
|
||||||
TrashBinSet bins = new TrashBinSet();
|
|
||||||
// ParseTrash still works, without changes:
|
|
||||||
ParseTrash.fillBin("doubledispatch", bin);
|
ParseTrash.fillBin("doubledispatch", bin);
|
||||||
|
TrashBinSet bins = new TrashBinSet();
|
||||||
// Sort from the master bin into the
|
// Sort from the master bin into the
|
||||||
// individually-typed bins:
|
// individually-typed bins:
|
||||||
bins.sortIntoBins(bin);
|
bins.sortIntoBins(bin);
|
||||||
// Perform sumValue for each bin...
|
// Sum value of each bin...
|
||||||
bins.binSet()
|
bins.binSet.forEach(tb ->
|
||||||
.forEach(tb -> Trash.sumValue(tb.v));
|
TrashValue.sum(tb.bin(), tb.type));
|
||||||
// ... and for the master bin
|
// ... and for the master bin:
|
||||||
Trash.sumValue(bin);
|
TrashValue.sum(bin, "Trash");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output: (First and Last 10 Lines)
|
/* Output:
|
||||||
Loading patterns.doubledispatch.Glass
|
Loading patterns.doubledispatch.Cardboard
|
||||||
Loading patterns.doubledispatch.Paper
|
Loading patterns.doubledispatch.Paper
|
||||||
Loading patterns.doubledispatch.Aluminum
|
Loading patterns.doubledispatch.Aluminum
|
||||||
Loading patterns.doubledispatch.Cardboard
|
Loading patterns.doubledispatch.Glass
|
||||||
weight of patterns.doubledispatch.Aluminum = 89.0
|
Aluminum weight: 1.80 * price: 1.67 = 3.01
|
||||||
weight of patterns.doubledispatch.Aluminum = 76.0
|
Aluminum weight: 3.40 * price: 1.67 = 5.68
|
||||||
weight of patterns.doubledispatch.Aluminum = 25.0
|
Aluminum weight: 2.70 * price: 1.67 = 4.51
|
||||||
weight of patterns.doubledispatch.Aluminum = 34.0
|
Total Aluminum value = 13.19
|
||||||
weight of patterns.doubledispatch.Aluminum = 27.0
|
Paper weight: 8.00 * price: 0.10 = 0.80
|
||||||
weight of patterns.doubledispatch.Aluminum = 18.0
|
Paper weight: 6.60 * price: 0.10 = 0.66
|
||||||
...________...________...________...________...
|
Paper weight: 9.10 * price: 0.10 = 0.91
|
||||||
weight of patterns.doubledispatch.Aluminum = 93.0
|
Total Paper value = 2.37
|
||||||
weight of patterns.doubledispatch.Glass = 93.0
|
Glass weight: 5.40 * price: 0.23 = 1.24
|
||||||
weight of patterns.doubledispatch.Paper = 80.0
|
Glass weight: 4.30 * price: 0.23 = 0.99
|
||||||
weight of patterns.doubledispatch.Glass = 36.0
|
Glass weight: 3.60 * price: 0.23 = 0.83
|
||||||
weight of patterns.doubledispatch.Glass = 12.0
|
Total Glass value = 3.06
|
||||||
weight of patterns.doubledispatch.Glass = 60.0
|
Cardboard weight: 4.40 * price: 0.11 = 0.48
|
||||||
weight of patterns.doubledispatch.Paper = 66.0
|
Cardboard weight: 2.20 * price: 0.11 = 0.24
|
||||||
weight of patterns.doubledispatch.Aluminum = 36.0
|
Cardboard weight: 1.20 * price: 0.11 = 0.13
|
||||||
weight of patterns.doubledispatch.Cardboard = 22.0
|
Total Cardboard value = 0.86
|
||||||
Total value = 1086.0599818825722
|
Cardboard weight: 4.40 * price: 0.11 = 0.48
|
||||||
|
Paper weight: 8.00 * price: 0.10 = 0.80
|
||||||
|
Aluminum weight: 1.80 * price: 1.67 = 3.01
|
||||||
|
Glass weight: 5.40 * price: 0.23 = 1.24
|
||||||
|
Aluminum weight: 3.40 * price: 1.67 = 5.68
|
||||||
|
Cardboard weight: 2.20 * price: 0.11 = 0.24
|
||||||
|
Glass weight: 4.30 * price: 0.23 = 0.99
|
||||||
|
Cardboard weight: 1.20 * price: 0.11 = 0.13
|
||||||
|
Paper weight: 6.60 * price: 0.10 = 0.66
|
||||||
|
Aluminum weight: 2.70 * price: 1.67 = 4.51
|
||||||
|
Paper weight: 9.10 * price: 0.10 = 0.91
|
||||||
|
Glass weight: 3.60 * price: 0.23 = 0.83
|
||||||
|
Total Trash value = 19.48
|
||||||
*/
|
*/
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Glass for double dispatching
|
// Glass with double dispatching.
|
||||||
package patterns.doubledispatch;
|
package patterns.doubledispatch;
|
||||||
import patterns.trash.*;
|
import patterns.trash.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Glass extends patterns.trash.Glass
|
public class Glass extends patterns.trash.Glass
|
||||||
implements TypedBinMember {
|
implements TypedBinMember {
|
||||||
public Glass(double wt) { super(wt); }
|
public Glass(double wt) { super(wt); }
|
||||||
@Override
|
@Override
|
||||||
public boolean addToBin(List<TypedBin> tbins) {
|
public boolean addToBin(List<TypedBin> tbins) {
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Paper for double dispatching
|
// Paper with double dispatching.
|
||||||
package patterns.doubledispatch;
|
package patterns.doubledispatch;
|
||||||
import patterns.trash.*;
|
import patterns.trash.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Paper extends patterns.trash.Paper
|
public class Paper extends patterns.trash.Paper
|
||||||
implements TypedBinMember {
|
implements TypedBinMember {
|
||||||
public Paper(double wt) { super(wt); }
|
public Paper(double wt) { super(wt); }
|
||||||
@Override
|
@Override
|
||||||
public boolean addToBin(List<TypedBin> tbins) {
|
public boolean addToBin(List<TypedBin> tbins) {
|
||||||
|
@ -2,15 +2,24 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// A List that can grab the right type
|
// A List that can grab the right type.
|
||||||
package patterns.doubledispatch;
|
package patterns.doubledispatch;
|
||||||
import patterns.trash.*;
|
import patterns.trash.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class TypedBin {
|
public class TypedBin {
|
||||||
List<Trash> v = new ArrayList<>();
|
private List<Trash> typedBin =
|
||||||
|
new ArrayList<>();
|
||||||
|
public final String type;
|
||||||
|
public TypedBin(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
public List<Trash> bin() {
|
||||||
|
// Returns a copy of typedBin:
|
||||||
|
return new ArrayList<Trash>(typedBin);
|
||||||
|
}
|
||||||
protected boolean addIt(Trash t) {
|
protected boolean addIt(Trash t) {
|
||||||
v.add(t);
|
typedBin.add(t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public boolean add(Aluminum a) {
|
public boolean add(Aluminum a) {
|
||||||
|
@ -2,13 +2,12 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// An interface for adding the double dispatching
|
// Adapts the double-dispatching
|
||||||
// method to the trash hierarchy without
|
// method into the trash hierarchy without
|
||||||
// modifying the original hierarchy
|
// modifying the original hierarchy.
|
||||||
package patterns.doubledispatch;
|
package patterns.doubledispatch;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public interface TypedBinMember {
|
public interface TypedBinMember {
|
||||||
// The new method:
|
|
||||||
boolean addToBin(List<TypedBin> bins);
|
boolean addToBin(List<TypedBin> bins);
|
||||||
}
|
}
|
||||||
|
@ -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
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Demonstration of "Observer" pattern
|
// Demonstration of the Observer pattern.
|
||||||
// {java patterns.observer.ObservedFlower}
|
// {java patterns.observer.ObservedFlower}
|
||||||
package patterns.observer;
|
package patterns.observer;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.*;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
class Flower {
|
class Flower {
|
||||||
private boolean isOpen;
|
private boolean isOpen = false;
|
||||||
private boolean alreadyOpen;
|
private boolean alreadyOpen = false;
|
||||||
private boolean alreadyClosed;
|
private boolean alreadyClosed = false;
|
||||||
Flower() { isOpen = false; }
|
Observable opening = new Observable() {
|
||||||
OpenNotifier opening = new OpenNotifier();
|
@Override public void notifyObservers() {
|
||||||
CloseNotifier closing = new CloseNotifier();
|
if(isOpen && !alreadyOpen) {
|
||||||
|
setChanged();
|
||||||
|
super.notifyObservers();
|
||||||
|
alreadyOpen = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Observable closing = new Observable() {
|
||||||
|
@Override public void notifyObservers() {
|
||||||
|
if(!isOpen && !alreadyClosed) {
|
||||||
|
setChanged();
|
||||||
|
super.notifyObservers();
|
||||||
|
alreadyClosed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
public void open() { // Opens its petals
|
public void open() { // Opens its petals
|
||||||
isOpen = true;
|
isOpen = true;
|
||||||
opening.notifyObservers();
|
opening.notifyObservers();
|
||||||
@ -25,55 +41,32 @@ class Flower {
|
|||||||
closing.notifyObservers();
|
closing.notifyObservers();
|
||||||
alreadyOpen = false;
|
alreadyOpen = false;
|
||||||
}
|
}
|
||||||
class OpenNotifier extends Observable {
|
|
||||||
@Override public void notifyObservers() {
|
|
||||||
if(isOpen && !alreadyOpen) {
|
|
||||||
setChanged();
|
|
||||||
super.notifyObservers();
|
|
||||||
alreadyOpen = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class CloseNotifier extends Observable{
|
|
||||||
@Override public void notifyObservers() {
|
|
||||||
if(!isOpen && !alreadyClosed) {
|
|
||||||
setChanged();
|
|
||||||
super.notifyObservers();
|
|
||||||
alreadyClosed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
class Bee {
|
class Bee {
|
||||||
private String name;
|
private String id;
|
||||||
Bee(String nm) { name = nm; }
|
Bee(String name) { id = name; }
|
||||||
// Observe openings:
|
// Observe openings:
|
||||||
public Observer openObserver() {
|
public final Observer whenOpened = (ob, a) ->
|
||||||
return (ob, a) -> System.out.println(
|
System.out.println(
|
||||||
"Bee " + name + "'s breakfast time!");
|
"Bee " + id + "'s breakfast time!");
|
||||||
}
|
|
||||||
// Observe closings:
|
// Observe closings:
|
||||||
public Observer closeObserver() {
|
public final Observer whenClosed = (ob, a) ->
|
||||||
return (ob, a) -> System.out.println(
|
System.out.println(
|
||||||
"Bee " + name + "'s bed time!");
|
"Bee " + id + "'s bed time!");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
class Hummingbird {
|
class Hummingbird {
|
||||||
private String name;
|
private String id;
|
||||||
Hummingbird(String nm) { name = nm; }
|
Hummingbird(String name) { id = name; }
|
||||||
public Observer openObserver() {
|
public final Observer whenOpened = (ob, a) ->
|
||||||
return (ob, a) -> System.out.println(
|
System.out.println("Hummingbird " +
|
||||||
"Hummingbird " + name +
|
id + "'s breakfast time!");
|
||||||
"'s breakfast time!");
|
public final Observer whenClosed = (ob, a) ->
|
||||||
}
|
System.out.println("Hummingbird " +
|
||||||
public Observer closeObserver() {
|
id + "'s bed time!");
|
||||||
return (ob, a) -> System.out.println(
|
|
||||||
"Hummingbird " + name + "'s bed time!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ObservedFlower {
|
public class ObservedFlower {
|
||||||
@ -85,39 +78,46 @@ public class ObservedFlower {
|
|||||||
Hummingbird
|
Hummingbird
|
||||||
ha = new Hummingbird("A"),
|
ha = new Hummingbird("A"),
|
||||||
hb = new Hummingbird("B");
|
hb = new Hummingbird("B");
|
||||||
f.opening.addObserver(ha.openObserver());
|
f.opening.addObserver(ha.whenOpened);
|
||||||
f.opening.addObserver(hb.openObserver());
|
f.opening.addObserver(hb.whenOpened);
|
||||||
f.opening.addObserver(ba.openObserver());
|
f.opening.addObserver(ba.whenOpened);
|
||||||
f.opening.addObserver(bb.openObserver());
|
f.opening.addObserver(bb.whenOpened);
|
||||||
f.closing.addObserver(ha.closeObserver());
|
f.closing.addObserver(ha.whenClosed);
|
||||||
f.closing.addObserver(hb.closeObserver());
|
f.closing.addObserver(hb.whenClosed);
|
||||||
f.closing.addObserver(ba.closeObserver());
|
f.closing.addObserver(ba.whenClosed);
|
||||||
f.closing.addObserver(bb.closeObserver());
|
f.closing.addObserver(bb.whenClosed);
|
||||||
// Hummingbird B decides to sleep in:
|
// Hummingbird B decides to sleep in.
|
||||||
f.opening.deleteObserver(hb.openObserver());
|
// Removing whenOpened stops open updates.
|
||||||
|
f.opening.deleteObserver(hb.whenOpened);
|
||||||
// A change that interests observers:
|
// A change that interests observers:
|
||||||
f.open();
|
f.open();
|
||||||
f.open(); // It's already open, no change.
|
f.open(); // No effect: it's already open.
|
||||||
// Bee A doesn't want to go to bed:
|
System.out.println("---------------");
|
||||||
f.closing.deleteObserver(ba.closeObserver());
|
// Bee A doesn't want to go to bed.
|
||||||
|
// Removing whenClosed stops close updates.
|
||||||
|
f.closing.deleteObserver(ba.whenClosed);
|
||||||
f.close();
|
f.close();
|
||||||
f.close(); // It's already closed; no change
|
System.out.println("+++++++++++++++");
|
||||||
|
f.close(); // No effect: it's already closed.
|
||||||
|
System.out.println("===============");
|
||||||
f.opening.deleteObservers();
|
f.opening.deleteObservers();
|
||||||
f.open();
|
f.open(); // No observers to update.
|
||||||
f.close();
|
System.out.println("###############");
|
||||||
|
f.close(); // Close observers are still there.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output:
|
/* Output:
|
||||||
Bee B's breakfast time!
|
Bee B's breakfast time!
|
||||||
Bee A's breakfast time!
|
Bee A's breakfast time!
|
||||||
Hummingbird B's breakfast time!
|
|
||||||
Hummingbird A's breakfast time!
|
Hummingbird A's breakfast time!
|
||||||
|
---------------
|
||||||
Bee B's bed time!
|
Bee B's bed time!
|
||||||
Bee A's bed time!
|
|
||||||
Hummingbird B's bed time!
|
Hummingbird B's bed time!
|
||||||
Hummingbird A's bed time!
|
Hummingbird A's bed time!
|
||||||
|
+++++++++++++++
|
||||||
|
===============
|
||||||
|
###############
|
||||||
Bee B's bed time!
|
Bee B's bed time!
|
||||||
Bee A's bed time!
|
|
||||||
Hummingbird B's bed time!
|
Hummingbird B's bed time!
|
||||||
Hummingbird A's bed time!
|
Hummingbird A's bed time!
|
||||||
*/
|
*/
|
||||||
|
@ -2,72 +2,25 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Recycling with RTTI
|
// Recycling with reflection.
|
||||||
// {java patterns.recyclea.RecycleA}
|
// {java patterns.recyclea.RecycleA}
|
||||||
package patterns.recyclea;
|
package patterns.recyclea;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.*;
|
import java.util.function.*;
|
||||||
import java.util.stream.*;
|
import java.util.stream.*;
|
||||||
|
import patterns.trash.*;
|
||||||
|
|
||||||
abstract class Trash {
|
class SimpleFactory {
|
||||||
double weight;
|
static final
|
||||||
Trash(double wt) { weight = wt; }
|
List<Function<Double, Trash>> constructors =
|
||||||
abstract double value();
|
|
||||||
// Sums the value of Trash in a bin:
|
|
||||||
private static double val;
|
|
||||||
static void sumValue(List<? extends Trash> bin) {
|
|
||||||
val = 0.0f;
|
|
||||||
bin.forEach( t -> {
|
|
||||||
// Polymorphism in action:
|
|
||||||
val += t.weight * t.value();
|
|
||||||
System.out.println(
|
|
||||||
"weight of " +
|
|
||||||
// Using RTTI to get type
|
|
||||||
// information about the class:
|
|
||||||
t.getClass().getSimpleName() +
|
|
||||||
" = " + t.weight);
|
|
||||||
});
|
|
||||||
System.out.println("Total value = " + val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Aluminum extends Trash {
|
|
||||||
static double val = 1.67f;
|
|
||||||
Aluminum(double wt) { super(wt); }
|
|
||||||
@Override double value() { return val; }
|
|
||||||
static void value(double newval) {
|
|
||||||
val = newval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Paper extends Trash {
|
|
||||||
static double val = 0.10f;
|
|
||||||
Paper(double wt) { super(wt); }
|
|
||||||
@Override double value() { return val; }
|
|
||||||
static void value(double newval) {
|
|
||||||
val = newval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Glass extends Trash {
|
|
||||||
static double val = 0.23f;
|
|
||||||
Glass(double wt) { super(wt); }
|
|
||||||
@Override double value() { return val; }
|
|
||||||
static void value(double newval) {
|
|
||||||
val = newval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TrashFactory {
|
|
||||||
static List<Function<Double, Trash>> ttypes =
|
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
Aluminum::new, Paper::new, Glass::new);
|
Aluminum::new, Paper::new, Glass::new);
|
||||||
static final int SZ = ttypes.size();
|
static final int SIZE = constructors.size();
|
||||||
private static SplittableRandom rand =
|
private static SplittableRandom rand =
|
||||||
new SplittableRandom(47);
|
new SplittableRandom(42);
|
||||||
public static Trash newTrash() {
|
public static Trash random() {
|
||||||
return ttypes
|
return constructors
|
||||||
.get(rand.nextInt(SZ))
|
.get(rand.nextInt(SIZE))
|
||||||
.apply(rand.nextDouble());
|
.apply(rand.nextDouble());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,50 +28,37 @@ class TrashFactory {
|
|||||||
public class RecycleA {
|
public class RecycleA {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
List<Trash> bin =
|
List<Trash> bin =
|
||||||
Stream.generate(TrashFactory::newTrash)
|
Stream.generate(SimpleFactory::random)
|
||||||
.limit(25)
|
.limit(10)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
List<Glass> glassBin = new ArrayList<>();
|
Bins bins = new Bins(bin);
|
||||||
List<Paper> paperBin = new ArrayList<>();
|
bins.show();
|
||||||
List<Aluminum> alBin = new ArrayList<>();
|
|
||||||
// Sort the Trash:
|
|
||||||
bin.forEach( t -> {
|
|
||||||
// RTTI to discover Trash type:
|
|
||||||
if(t instanceof Aluminum)
|
|
||||||
alBin.add((Aluminum)t);
|
|
||||||
if(t instanceof Paper)
|
|
||||||
paperBin.add((Paper)t);
|
|
||||||
if(t instanceof Glass)
|
|
||||||
glassBin.add((Glass)t);
|
|
||||||
});
|
|
||||||
Trash.sumValue(alBin);
|
|
||||||
Trash.sumValue(paperBin);
|
|
||||||
Trash.sumValue(glassBin);
|
|
||||||
Trash.sumValue(bin);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output: (First and Last 11 Lines)
|
/* Output:
|
||||||
weight of Aluminum = 0.2893030122276371
|
Aluminum weight: 0.34 * price: 1.67 = 0.57
|
||||||
weight of Aluminum = 0.1970234961398979
|
Aluminum weight: 0.62 * price: 1.67 = 1.03
|
||||||
weight of Aluminum = 0.36295525806274787
|
Aluminum weight: 0.49 * price: 1.67 = 0.82
|
||||||
weight of Aluminum = 0.4825532324565849
|
Aluminum weight: 0.50 * price: 1.67 = 0.83
|
||||||
weight of Aluminum = 0.8036398273294586
|
Total Aluminum value = 3.26
|
||||||
weight of Aluminum = 0.510430896154935
|
Paper weight: 0.69 * price: 0.10 = 0.07
|
||||||
weight of Aluminum = 0.6703377164093444
|
Total Paper value = 0.07
|
||||||
weight of Aluminum = 0.41477933066243455
|
Glass weight: 0.16 * price: 0.23 = 0.04
|
||||||
weight of Aluminum = 0.3603022312124007
|
Glass weight: 0.87 * price: 0.23 = 0.20
|
||||||
weight of Aluminum = 0.43690089841661006
|
Glass weight: 0.80 * price: 0.23 = 0.18
|
||||||
weight of Aluminum = 0.6708820087907101
|
Glass weight: 0.52 * price: 0.23 = 0.12
|
||||||
...________...________...________...________...
|
Glass weight: 0.20 * price: 0.23 = 0.05
|
||||||
weight of Aluminum = 0.41477933066243455
|
Total Glass value = 0.59
|
||||||
weight of Aluminum = 0.3603022312124007
|
Total Cardboard value = 0.00
|
||||||
weight of Aluminum = 0.43690089841661006
|
Glass weight: 0.16 * price: 0.23 = 0.04
|
||||||
weight of Glass = 0.5999637765664924
|
Aluminum weight: 0.34 * price: 1.67 = 0.57
|
||||||
weight of Glass = 0.7748836191212746
|
Glass weight: 0.87 * price: 0.23 = 0.20
|
||||||
weight of Paper = 0.5735994548427199
|
Glass weight: 0.80 * price: 0.23 = 0.18
|
||||||
weight of Glass = 0.5362827750851034
|
Aluminum weight: 0.62 * price: 1.67 = 1.03
|
||||||
weight of Aluminum = 0.6708820087907101
|
Aluminum weight: 0.49 * price: 1.67 = 0.82
|
||||||
weight of Paper = 0.8370669795210507
|
Glass weight: 0.52 * price: 0.23 = 0.12
|
||||||
weight of Glass = 0.3397919679731668
|
Glass weight: 0.20 * price: 0.23 = 0.05
|
||||||
Total value = 9.90671597531968
|
Aluminum weight: 0.50 * price: 1.67 = 0.83
|
||||||
|
Paper weight: 0.69 * price: 0.10 = 0.07
|
||||||
|
Total Trash value = 3.91
|
||||||
*/
|
*/
|
||||||
|
@ -10,47 +10,43 @@ import java.util.*;
|
|||||||
public class RecycleB {
|
public class RecycleB {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
List<Trash> bin = new ArrayList<>();
|
List<Trash> bin = new ArrayList<>();
|
||||||
// Fill up the Trash bin:
|
|
||||||
ParseTrash.fillBin("trash", bin);
|
ParseTrash.fillBin("trash", bin);
|
||||||
List<Glass> glassBin = new ArrayList<>();
|
Bins bins = new Bins(bin);
|
||||||
List<Paper> paperBin = new ArrayList<>();
|
bins.show();
|
||||||
List<Aluminum> alBin = new ArrayList<>();
|
|
||||||
// Sort the Trash:
|
|
||||||
bin.forEach( t -> {
|
|
||||||
// RTTI to discover Trash type:
|
|
||||||
if(t instanceof Aluminum)
|
|
||||||
alBin.add((Aluminum)t);
|
|
||||||
if(t instanceof Paper)
|
|
||||||
paperBin.add((Paper)t);
|
|
||||||
if(t instanceof Glass)
|
|
||||||
glassBin.add((Glass)t);
|
|
||||||
});
|
|
||||||
Trash.sumValue(alBin);
|
|
||||||
Trash.sumValue(paperBin);
|
|
||||||
Trash.sumValue(glassBin);
|
|
||||||
Trash.sumValue(bin);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output: (First and Last 10 Lines)
|
/* Output:
|
||||||
Loading patterns.trash.Glass
|
Loading patterns.trash.Cardboard
|
||||||
Loading patterns.trash.Paper
|
Loading patterns.trash.Paper
|
||||||
Loading patterns.trash.Aluminum
|
Loading patterns.trash.Aluminum
|
||||||
Loading patterns.trash.Cardboard
|
Loading patterns.trash.Glass
|
||||||
weight of patterns.trash.Aluminum = 89.0
|
Aluminum weight: 1.80 * price: 1.67 = 3.01
|
||||||
weight of patterns.trash.Aluminum = 76.0
|
Aluminum weight: 3.40 * price: 1.67 = 5.68
|
||||||
weight of patterns.trash.Aluminum = 25.0
|
Aluminum weight: 2.70 * price: 1.67 = 4.51
|
||||||
weight of patterns.trash.Aluminum = 34.0
|
Total Aluminum value = 13.19
|
||||||
weight of patterns.trash.Aluminum = 27.0
|
Paper weight: 8.00 * price: 0.10 = 0.80
|
||||||
weight of patterns.trash.Aluminum = 18.0
|
Paper weight: 6.60 * price: 0.10 = 0.66
|
||||||
...________...________...________...________...
|
Paper weight: 9.10 * price: 0.10 = 0.91
|
||||||
weight of patterns.trash.Aluminum = 93.0
|
Total Paper value = 2.37
|
||||||
weight of patterns.trash.Glass = 93.0
|
Glass weight: 5.40 * price: 0.23 = 1.24
|
||||||
weight of patterns.trash.Paper = 80.0
|
Glass weight: 4.30 * price: 0.23 = 0.99
|
||||||
weight of patterns.trash.Glass = 36.0
|
Glass weight: 3.60 * price: 0.23 = 0.83
|
||||||
weight of patterns.trash.Glass = 12.0
|
Total Glass value = 3.06
|
||||||
weight of patterns.trash.Glass = 60.0
|
Cardboard weight: 4.40 * price: 0.11 = 0.48
|
||||||
weight of patterns.trash.Paper = 66.0
|
Cardboard weight: 2.20 * price: 0.11 = 0.24
|
||||||
weight of patterns.trash.Aluminum = 36.0
|
Cardboard weight: 1.20 * price: 0.11 = 0.13
|
||||||
weight of patterns.trash.Cardboard = 22.0
|
Total Cardboard value = 0.86
|
||||||
Total value = 1086.0599818825722
|
Cardboard weight: 4.40 * price: 0.11 = 0.48
|
||||||
|
Paper weight: 8.00 * price: 0.10 = 0.80
|
||||||
|
Aluminum weight: 1.80 * price: 1.67 = 3.01
|
||||||
|
Glass weight: 5.40 * price: 0.23 = 1.24
|
||||||
|
Aluminum weight: 3.40 * price: 1.67 = 5.68
|
||||||
|
Cardboard weight: 2.20 * price: 0.11 = 0.24
|
||||||
|
Glass weight: 4.30 * price: 0.23 = 0.99
|
||||||
|
Cardboard weight: 1.20 * price: 0.11 = 0.13
|
||||||
|
Paper weight: 6.60 * price: 0.10 = 0.66
|
||||||
|
Aluminum weight: 2.70 * price: 1.67 = 4.51
|
||||||
|
Paper weight: 9.10 * price: 0.10 = 0.91
|
||||||
|
Glass weight: 3.60 * price: 0.23 = 0.83
|
||||||
|
Total Trash value = 19.48
|
||||||
*/
|
*/
|
||||||
|
@ -2,83 +2,105 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Adding more objects to the recycling problem
|
|
||||||
// {java patterns.recyclec.RecycleC}
|
// {java patterns.recyclec.RecycleC}
|
||||||
package patterns.recyclec;
|
package patterns.recyclec;
|
||||||
import patterns.trash.*;
|
import patterns.trash.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
// A List that admits only the right type:
|
// A List that only admits the right type:
|
||||||
class Tbin<T extends Trash> extends ArrayList<T> {
|
class
|
||||||
Class<T> binType;
|
TrashBin<T extends Trash> extends ArrayList<T> {
|
||||||
Tbin(Class<T> type) {
|
final Class<T> binType;
|
||||||
binType = type;
|
TrashBin(Class<T> binType) {
|
||||||
|
this.binType = binType;
|
||||||
}
|
}
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
boolean grab(Trash t) {
|
boolean grab(Trash t) {
|
||||||
// Comparing class types:
|
// Compare class types:
|
||||||
if(t.getClass().equals(binType)) {
|
if(t.getClass().equals(binType)) {
|
||||||
add((T)t); // Downcast to this TBin's type
|
add((T)t); // Downcast to this TrashBin type
|
||||||
return true; // Object grabbed
|
return true; // Trash grabbed
|
||||||
}
|
}
|
||||||
return false; // Object not grabbed
|
return false; // Trash not grabbed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TbinList<T extends Trash>
|
class TrashBinList<T extends Trash>
|
||||||
extends ArrayList<Tbin<? extends T>> { // [1]
|
extends ArrayList<TrashBin<? extends T>> { // [1]
|
||||||
boolean sort(T t) {
|
@SuppressWarnings("unchecked")
|
||||||
for(Tbin<? extends T> ts : this)
|
public TrashBinList(Class<? extends T>... types) {
|
||||||
|
for(Class<? extends T> type : types)
|
||||||
|
add(new TrashBin<>(type));
|
||||||
|
}
|
||||||
|
public boolean sort(T t) {
|
||||||
|
for(TrashBin<? extends T> ts : this)
|
||||||
if(ts.grab(t))
|
if(ts.grab(t))
|
||||||
return true;
|
return true;
|
||||||
return false; // bin not found for t
|
return false; // TrashBin not found for t
|
||||||
}
|
}
|
||||||
void sortBin(Tbin<T> bin) { // [2]
|
public void sortBin(TrashBin<T> bin) { // [2]
|
||||||
for(T aBin : bin)
|
for(T trash : bin)
|
||||||
if(!sort(aBin))
|
if(!sort(trash))
|
||||||
System.err.println("Bin not found");
|
throw new RuntimeException(
|
||||||
|
"Bin not found for " + trash);
|
||||||
|
}
|
||||||
|
public void show() {
|
||||||
|
for(TrashBin<? extends T> tbin : this) {
|
||||||
|
String typeName = tbin.binType.getSimpleName();
|
||||||
|
TrashValue.sum(tbin, typeName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RecycleC {
|
public class RecycleC {
|
||||||
static Tbin<Trash> bin = new Tbin<>(Trash.class);
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Fill up the Trash bin:
|
TrashBin<Trash> bin =
|
||||||
|
new TrashBin<>(Trash.class);
|
||||||
ParseTrash.fillBin("trash", bin);
|
ParseTrash.fillBin("trash", bin);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
TbinList<Trash> trashBins = new TbinList<>();
|
TrashBinList<Trash> trashBins =
|
||||||
trashBins.add(new Tbin<>(Aluminum.class));
|
new TrashBinList<>(
|
||||||
trashBins.add(new Tbin<>(Paper.class));
|
Aluminum.class, Paper.class, Glass.class,
|
||||||
trashBins.add(new Tbin<>(Glass.class));
|
// Add one item:
|
||||||
// add one line here: // [3]
|
Cardboard.class // [3]
|
||||||
trashBins.add(new Tbin<>(Cardboard.class));
|
);
|
||||||
|
|
||||||
trashBins.sortBin(bin); // [4]
|
trashBins.sortBin(bin); // [4]
|
||||||
|
trashBins.show();
|
||||||
trashBins.forEach(Trash::sumValue);
|
TrashValue.sum(bin, "Trash");
|
||||||
Trash.sumValue(bin);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output: (First and Last 10 Lines)
|
/* Output:
|
||||||
Loading patterns.trash.Glass
|
Loading patterns.trash.Cardboard
|
||||||
Loading patterns.trash.Paper
|
Loading patterns.trash.Paper
|
||||||
Loading patterns.trash.Aluminum
|
Loading patterns.trash.Aluminum
|
||||||
Loading patterns.trash.Cardboard
|
Loading patterns.trash.Glass
|
||||||
weight of patterns.trash.Aluminum = 89.0
|
Aluminum weight: 1.80 * price: 1.67 = 3.01
|
||||||
weight of patterns.trash.Aluminum = 76.0
|
Aluminum weight: 3.40 * price: 1.67 = 5.68
|
||||||
weight of patterns.trash.Aluminum = 25.0
|
Aluminum weight: 2.70 * price: 1.67 = 4.51
|
||||||
weight of patterns.trash.Aluminum = 34.0
|
Total Aluminum value = 13.19
|
||||||
weight of patterns.trash.Aluminum = 27.0
|
Paper weight: 8.00 * price: 0.10 = 0.80
|
||||||
weight of patterns.trash.Aluminum = 18.0
|
Paper weight: 6.60 * price: 0.10 = 0.66
|
||||||
...________...________...________...________...
|
Paper weight: 9.10 * price: 0.10 = 0.91
|
||||||
weight of patterns.trash.Aluminum = 93.0
|
Total Paper value = 2.37
|
||||||
weight of patterns.trash.Glass = 93.0
|
Glass weight: 5.40 * price: 0.23 = 1.24
|
||||||
weight of patterns.trash.Paper = 80.0
|
Glass weight: 4.30 * price: 0.23 = 0.99
|
||||||
weight of patterns.trash.Glass = 36.0
|
Glass weight: 3.60 * price: 0.23 = 0.83
|
||||||
weight of patterns.trash.Glass = 12.0
|
Total Glass value = 3.06
|
||||||
weight of patterns.trash.Glass = 60.0
|
Cardboard weight: 4.40 * price: 0.11 = 0.48
|
||||||
weight of patterns.trash.Paper = 66.0
|
Cardboard weight: 2.20 * price: 0.11 = 0.24
|
||||||
weight of patterns.trash.Aluminum = 36.0
|
Cardboard weight: 1.20 * price: 0.11 = 0.13
|
||||||
weight of patterns.trash.Cardboard = 22.0
|
Total Cardboard value = 0.86
|
||||||
Total value = 1086.0599818825722
|
Cardboard weight: 4.40 * price: 0.11 = 0.48
|
||||||
|
Paper weight: 8.00 * price: 0.10 = 0.80
|
||||||
|
Aluminum weight: 1.80 * price: 1.67 = 3.01
|
||||||
|
Glass weight: 5.40 * price: 0.23 = 1.24
|
||||||
|
Aluminum weight: 3.40 * price: 1.67 = 5.68
|
||||||
|
Cardboard weight: 2.20 * price: 0.11 = 0.24
|
||||||
|
Glass weight: 4.30 * price: 0.23 = 0.99
|
||||||
|
Cardboard weight: 1.20 * price: 0.11 = 0.13
|
||||||
|
Paper weight: 6.60 * price: 0.10 = 0.66
|
||||||
|
Aluminum weight: 2.70 * price: 1.67 = 4.51
|
||||||
|
Paper weight: 9.10 * price: 0.10 = 0.91
|
||||||
|
Glass weight: 3.60 * price: 0.23 = 0.83
|
||||||
|
Total Trash value = 19.48
|
||||||
*/
|
*/
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// The StateMachine pattern and Template method
|
// The State Machine pattern.
|
||||||
// {java patterns.state.StateMachineDemo}
|
// {java patterns.state.StateMachineDemo}
|
||||||
package patterns.state;
|
package patterns.state;
|
||||||
|
import java.util.*;
|
||||||
import onjava.Nap;
|
import onjava.Nap;
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
@ -16,7 +17,7 @@ abstract class StateMachine {
|
|||||||
protected abstract boolean changeState();
|
protected abstract boolean changeState();
|
||||||
// Template method:
|
// Template method:
|
||||||
protected final void runAll() {
|
protected final void runAll() {
|
||||||
while(changeState()) // Customizable
|
while(changeState())
|
||||||
currentState.run();
|
currentState.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,20 +47,19 @@ class Rinse implements State {
|
|||||||
|
|
||||||
class Washer extends StateMachine {
|
class Washer extends StateMachine {
|
||||||
private int i = 0;
|
private int i = 0;
|
||||||
// The state table:
|
private Iterator<State> states =
|
||||||
private State[] states = {
|
Arrays.asList(
|
||||||
new Wash(), new Spin(),
|
new Wash(), new Spin(),
|
||||||
new Rinse(), new Spin(),
|
new Rinse(), new Spin()
|
||||||
};
|
).iterator();
|
||||||
Washer() { runAll(); }
|
Washer() { runAll(); }
|
||||||
@Override public boolean changeState() {
|
@Override public boolean changeState() {
|
||||||
if(i < states.length) {
|
if(!states.hasNext())
|
||||||
// Change the state by setting the
|
|
||||||
// surrogate reference to a new object:
|
|
||||||
currentState = states[i++];
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
return false;
|
return false;
|
||||||
|
// Set the surrogate reference
|
||||||
|
// to a new State object:
|
||||||
|
currentState = states.next();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,13 +9,14 @@ import java.util.*;
|
|||||||
|
|
||||||
// The common strategy base type:
|
// The common strategy base type:
|
||||||
class FindMinima {
|
class FindMinima {
|
||||||
|
protected
|
||||||
Function<List<Double>, List<Double>> algorithm;
|
Function<List<Double>, List<Double>> algorithm;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The various strategies:
|
// The various strategies, each producing dummy data:
|
||||||
class LeastSquares extends FindMinima {
|
class LeastSquares extends FindMinima {
|
||||||
LeastSquares() {
|
LeastSquares() {
|
||||||
// Line is a sequence of points (Dummy data):
|
// Line is a sequence of points:
|
||||||
algorithm = (line) -> Arrays.asList(1.1, 2.2);
|
algorithm = (line) -> Arrays.asList(1.1, 2.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -35,8 +36,8 @@ class Bisection extends FindMinima {
|
|||||||
// The "Context" controls the strategy:
|
// The "Context" controls the strategy:
|
||||||
class MinimaSolver {
|
class MinimaSolver {
|
||||||
private FindMinima strategy;
|
private FindMinima strategy;
|
||||||
MinimaSolver(FindMinima strat) {
|
MinimaSolver(FindMinima strategy) {
|
||||||
strategy = strat;
|
this.strategy = strategy;
|
||||||
}
|
}
|
||||||
List<Double> minima(List<Double> line) {
|
List<Double> minima(List<Double> line) {
|
||||||
return strategy.algorithm.apply(line);
|
return strategy.algorithm.apply(line);
|
||||||
@ -54,11 +55,14 @@ public class StrategyPattern {
|
|||||||
1.0, 2.0, 1.0, 2.0, -1.0,
|
1.0, 2.0, 1.0, 2.0, -1.0,
|
||||||
3.0, 4.0, 5.0, 4.0 );
|
3.0, 4.0, 5.0, 4.0 );
|
||||||
System.out.println(solver.minima(line));
|
System.out.println(solver.minima(line));
|
||||||
|
solver.changeAlgorithm(new Perturbation());
|
||||||
|
System.out.println(solver.minima(line));
|
||||||
solver.changeAlgorithm(new Bisection());
|
solver.changeAlgorithm(new Bisection());
|
||||||
System.out.println(solver.minima(line));
|
System.out.println(solver.minima(line));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output:
|
/* Output:
|
||||||
[1.1, 2.2]
|
[1.1, 2.2]
|
||||||
|
[3.3, 4.4]
|
||||||
[5.5, 6.6]
|
[5.5, 6.6]
|
||||||
*/
|
*/
|
||||||
|
@ -9,6 +9,7 @@ import java.util.*;
|
|||||||
|
|
||||||
// "Context" is now incorporated:
|
// "Context" is now incorporated:
|
||||||
class FindMinima2 {
|
class FindMinima2 {
|
||||||
|
private
|
||||||
Function<List<Double>, List<Double>> algorithm;
|
Function<List<Double>, List<Double>> algorithm;
|
||||||
FindMinima2() { leastSquares(); } // default
|
FindMinima2() { leastSquares(); } // default
|
||||||
// The various strategies:
|
// The various strategies:
|
||||||
@ -33,11 +34,14 @@ public class StrategyPattern2 {
|
|||||||
1.0, 2.0, 1.0, 2.0, -1.0,
|
1.0, 2.0, 1.0, 2.0, -1.0,
|
||||||
3.0, 4.0, 5.0, 4.0 );
|
3.0, 4.0, 5.0, 4.0 );
|
||||||
System.out.println(solver.minima(line));
|
System.out.println(solver.minima(line));
|
||||||
|
solver.perturbation();
|
||||||
|
System.out.println(solver.minima(line));
|
||||||
solver.bisection();
|
solver.bisection();
|
||||||
System.out.println(solver.minima(line));
|
System.out.println(solver.minima(line));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output:
|
/* Output:
|
||||||
[1.1, 2.2]
|
[1.1, 2.2]
|
||||||
|
[3.3, 4.4]
|
||||||
[5.5, 6.6]
|
[5.5, 6.6]
|
||||||
*/
|
*/
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
package patterns.trash;
|
package patterns.trash;
|
||||||
|
|
||||||
public class Aluminum extends Trash {
|
public class Aluminum extends Trash {
|
||||||
private static double val = 1.67f;
|
|
||||||
public Aluminum(double wt) { super(wt); }
|
public Aluminum(double wt) { super(wt); }
|
||||||
@Override public double value() { return val; }
|
@Override public double price() {
|
||||||
public static void value(double newVal) {
|
return Price.ALUMINUM;
|
||||||
val = newVal;
|
}
|
||||||
|
// Ignore for now; to be used later:
|
||||||
|
@Override public void accept(Visitor v) {
|
||||||
|
v.visit(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
patterns/trash/Bins.java
Normal file
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;
|
package patterns.trash;
|
||||||
|
|
||||||
public class Cardboard extends Trash {
|
public class Cardboard extends Trash {
|
||||||
private static double val = 0.23f;
|
|
||||||
public Cardboard(double wt) { super(wt); }
|
public Cardboard(double wt) { super(wt); }
|
||||||
@Override public double value() { return val; }
|
@Override public double price() {
|
||||||
public static void value(double newVal) {
|
return Price.CARDBOARD;
|
||||||
val = newVal;
|
}
|
||||||
|
// Ignore for now; to be used later:
|
||||||
|
@Override public void accept(Visitor v) {
|
||||||
|
v.visit(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Any object that can be filled with Trash
|
// Any object that can be filled with Trash.
|
||||||
package patterns.trash;
|
package patterns.trash;
|
||||||
|
|
||||||
public interface Fillable<T extends Trash> {
|
public interface Fillable<T extends Trash> {
|
||||||
|
@ -2,15 +2,17 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Adapter that makes a List Fillable
|
// Adapter that makes a List Fillable.
|
||||||
package patterns.trash;
|
package patterns.trash;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class FillableList<T extends Trash>
|
public class FillableList<T extends Trash>
|
||||||
implements Fillable<T> {
|
implements Fillable<T> {
|
||||||
private List<T> v;
|
private List<T> list;
|
||||||
public FillableList(List<T> vv) {
|
public FillableList(List<T> list) {
|
||||||
v = vv;
|
this.list = list;
|
||||||
|
}
|
||||||
|
@Override public void addTrash(T t) {
|
||||||
|
list.add(t);
|
||||||
}
|
}
|
||||||
@Override public void addTrash(T t) { v.add(t); }
|
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
package patterns.trash;
|
package patterns.trash;
|
||||||
|
|
||||||
public class Glass extends Trash {
|
public class Glass extends Trash {
|
||||||
private static double val = 0.23f;
|
|
||||||
public Glass(double wt) { super(wt); }
|
public Glass(double wt) { super(wt); }
|
||||||
@Override public double value() { return val; }
|
@Override public double price() {
|
||||||
public static void value(double newVal) {
|
return Price.GLASS;
|
||||||
val = newVal;
|
}
|
||||||
|
// Ignore for now; to be used later:
|
||||||
|
@Override public void accept(Visitor v) {
|
||||||
|
v.visit(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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;
|
package patterns.trash;
|
||||||
|
|
||||||
public class Paper extends Trash {
|
public class Paper extends Trash {
|
||||||
private static double val = 0.10f;
|
|
||||||
public Paper(double wt) { super(wt); }
|
public Paper(double wt) { super(wt); }
|
||||||
@Override public double value() { return val; }
|
@Override public double price() {
|
||||||
public static void value(double newVal) {
|
return Price.PAPER;
|
||||||
val = newVal;
|
}
|
||||||
|
// Ignore for now; to be used later:
|
||||||
|
@Override public void accept(Visitor v) {
|
||||||
|
v.visit(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Open a file and parse its contents into
|
// Opens a file and parses its contents into
|
||||||
// Trash objects, placing each into a List
|
// Trash objects, placing each into a Fillable.
|
||||||
// {java patterns.trash.ParseTrash}
|
// {java patterns.trash.ParseTrash}
|
||||||
package patterns.trash;
|
package patterns.trash;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -13,79 +13,56 @@ import java.nio.file.*;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
|
||||||
public class ParseTrash {
|
public class ParseTrash {
|
||||||
|
public static String source = "Trash.dat";
|
||||||
public static <T extends Trash> void
|
public static <T extends Trash> void
|
||||||
fillBin(String pckg, Fillable<T> bin) {
|
fillBin(String packageName, Fillable<T> bin) {
|
||||||
|
DynaFactory factory =
|
||||||
|
new DynaFactory(packageName);
|
||||||
try {
|
try {
|
||||||
Files.lines(Paths.get("trash", "Trash.dat"))
|
Files.lines(Paths.get("trash", source))
|
||||||
// Remove empty lines and comment lines:
|
// Remove comments and empty lines:
|
||||||
.filter(line -> line.trim().length() != 0)
|
.filter(line -> line.trim().length() != 0)
|
||||||
.filter(line -> !line.startsWith("//"))
|
.filter(line -> !line.startsWith("//"))
|
||||||
.forEach( line -> {
|
.forEach(line -> {
|
||||||
String type = "patterns." + pckg + "." +
|
String type = line.substring(
|
||||||
line.substring(
|
|
||||||
0, line.indexOf(':')).trim();
|
0, line.indexOf(':')).trim();
|
||||||
double weight = Double.valueOf(
|
double weight = Double.valueOf(
|
||||||
line.substring(line.indexOf(':') + 1)
|
line.substring(line.indexOf(':') + 1)
|
||||||
.trim());
|
.trim());
|
||||||
bin.addTrash(Trash.factory(
|
bin.addTrash(factory.create(
|
||||||
new Trash.Info(type, weight)));
|
new TrashInfo(type, weight)));
|
||||||
});
|
});
|
||||||
} catch(IOException |
|
} catch(IOException | NumberFormatException e) {
|
||||||
NumberFormatException |
|
|
||||||
Trash.TrashClassNotFoundException |
|
|
||||||
Trash.CannotCreateTrashException e) {
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Special case to handle List:
|
// Special case to handle a List:
|
||||||
public static <T extends Trash> void
|
public static <T extends Trash> void
|
||||||
fillBin(String pckg, List<T> bin) {
|
fillBin(String packageName, List<T> bin) {
|
||||||
fillBin(pckg, new FillableList<>(bin));
|
fillBin(packageName, new FillableList<>(bin));
|
||||||
}
|
}
|
||||||
// Basic test:
|
// Basic test:
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
List<Trash> t = new ArrayList<>();
|
List<Trash> bin = new ArrayList<>();
|
||||||
fillBin("trash", t);
|
fillBin("trash", bin);
|
||||||
t.forEach(System.out::println);
|
bin.forEach(System.out::println);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Output:
|
/* Output:
|
||||||
Loading patterns.trash.Glass
|
Loading patterns.trash.Cardboard
|
||||||
Loading patterns.trash.Paper
|
Loading patterns.trash.Paper
|
||||||
Loading patterns.trash.Aluminum
|
Loading patterns.trash.Aluminum
|
||||||
Loading patterns.trash.Cardboard
|
Loading patterns.trash.Glass
|
||||||
patterns.trash.Glass w:54.0 v:0.23
|
Cardboard weight: 4.40 * price: 0.11 = 0.48
|
||||||
patterns.trash.Paper w:22.0 v:0.10
|
Paper weight: 8.00 * price: 0.10 = 0.80
|
||||||
patterns.trash.Paper w:11.0 v:0.10
|
Aluminum weight: 1.80 * price: 1.67 = 3.01
|
||||||
patterns.trash.Glass w:17.0 v:0.23
|
Glass weight: 5.40 * price: 0.23 = 1.24
|
||||||
patterns.trash.Aluminum w:89.0 v:1.67
|
Aluminum weight: 3.40 * price: 1.67 = 5.68
|
||||||
patterns.trash.Paper w:88.0 v:0.10
|
Cardboard weight: 2.20 * price: 0.11 = 0.24
|
||||||
patterns.trash.Aluminum w:76.0 v:1.67
|
Glass weight: 4.30 * price: 0.23 = 0.99
|
||||||
patterns.trash.Cardboard w:96.0 v:0.23
|
Cardboard weight: 1.20 * price: 0.11 = 0.13
|
||||||
patterns.trash.Aluminum w:25.0 v:1.67
|
Paper weight: 6.60 * price: 0.10 = 0.66
|
||||||
patterns.trash.Aluminum w:34.0 v:1.67
|
Aluminum weight: 2.70 * price: 1.67 = 4.51
|
||||||
patterns.trash.Glass w:11.0 v:0.23
|
Paper weight: 9.10 * price: 0.10 = 0.91
|
||||||
patterns.trash.Glass w:68.0 v:0.23
|
Glass weight: 3.60 * price: 0.23 = 0.83
|
||||||
patterns.trash.Glass w:43.0 v:0.23
|
|
||||||
patterns.trash.Aluminum w:27.0 v:1.67
|
|
||||||
patterns.trash.Cardboard w:44.0 v:0.23
|
|
||||||
patterns.trash.Aluminum w:18.0 v:1.67
|
|
||||||
patterns.trash.Paper w:91.0 v:0.10
|
|
||||||
patterns.trash.Glass w:63.0 v:0.23
|
|
||||||
patterns.trash.Glass w:50.0 v:0.23
|
|
||||||
patterns.trash.Glass w:80.0 v:0.23
|
|
||||||
patterns.trash.Aluminum w:81.0 v:1.67
|
|
||||||
patterns.trash.Cardboard w:12.0 v:0.23
|
|
||||||
patterns.trash.Glass w:12.0 v:0.23
|
|
||||||
patterns.trash.Glass w:54.0 v:0.23
|
|
||||||
patterns.trash.Aluminum w:36.0 v:1.67
|
|
||||||
patterns.trash.Aluminum w:93.0 v:1.67
|
|
||||||
patterns.trash.Glass w:93.0 v:0.23
|
|
||||||
patterns.trash.Paper w:80.0 v:0.10
|
|
||||||
patterns.trash.Glass w:36.0 v:0.23
|
|
||||||
patterns.trash.Glass w:12.0 v:0.23
|
|
||||||
patterns.trash.Glass w:60.0 v:0.23
|
|
||||||
patterns.trash.Paper w:66.0 v:0.10
|
|
||||||
patterns.trash.Aluminum w:36.0 v:1.67
|
|
||||||
patterns.trash.Cardboard w:22.0 v:0.23
|
|
||||||
*/
|
*/
|
||||||
|
13
patterns/trash/Price.java
Normal file
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
|
// patterns/trash/Trash.dat
|
||||||
Glass:54
|
Cardboard:4.4
|
||||||
Paper:22
|
Paper:8.0
|
||||||
Paper:11
|
Aluminum:1.8
|
||||||
Glass:17
|
Glass:5.4
|
||||||
Aluminum:89
|
Aluminum:3.4
|
||||||
Paper:88
|
Cardboard:2.2
|
||||||
Aluminum:76
|
Glass:4.3
|
||||||
Cardboard:96
|
Cardboard:1.2
|
||||||
Aluminum:25
|
Paper:6.6
|
||||||
Aluminum:34
|
Aluminum:2.7
|
||||||
Glass:11
|
Paper:9.1
|
||||||
Glass:68
|
Glass:3.6
|
||||||
Glass:43
|
|
||||||
Aluminum:27
|
|
||||||
Cardboard:44
|
|
||||||
Aluminum:18
|
|
||||||
Paper:91
|
|
||||||
Glass:63
|
|
||||||
Glass:50
|
|
||||||
Glass:80
|
|
||||||
Aluminum:81
|
|
||||||
Cardboard:12
|
|
||||||
Glass:12
|
|
||||||
Glass:54
|
|
||||||
Aluminum:36
|
|
||||||
Aluminum:93
|
|
||||||
Glass:93
|
|
||||||
Paper:80
|
|
||||||
Glass:36
|
|
||||||
Glass:12
|
|
||||||
Glass:60
|
|
||||||
Paper:66
|
|
||||||
Aluminum:36
|
|
||||||
Cardboard:22
|
|
||||||
|
@ -2,90 +2,21 @@
|
|||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Base class for Trash recycling examples
|
// Base class for Trash recycling examples.
|
||||||
package patterns.trash;
|
package patterns.trash;
|
||||||
import java.util.*;
|
|
||||||
import java.lang.reflect.*;
|
|
||||||
|
|
||||||
public abstract class Trash {
|
public abstract class Trash {
|
||||||
private double weight;
|
public final double weight;
|
||||||
public Trash(double wt) { weight = wt; }
|
public Trash(double weight) {
|
||||||
public Trash() {}
|
this.weight = weight;
|
||||||
public abstract double value();
|
|
||||||
public double weight() { return weight; }
|
|
||||||
// Sums the value of Trash in a bin:
|
|
||||||
static double val;
|
|
||||||
public static <T extends Trash>
|
|
||||||
void sumValue(List<? extends T> bin) {
|
|
||||||
val = 0.0f;
|
|
||||||
bin.forEach( t -> {
|
|
||||||
val += t.weight() * t.value();
|
|
||||||
System.out.println("weight of " +
|
|
||||||
// RTTI gets type information
|
|
||||||
// about the class:
|
|
||||||
t.getClass().getName() +
|
|
||||||
" = " + t.weight());
|
|
||||||
});
|
|
||||||
System.out.println("Total value = " + val);
|
|
||||||
}
|
}
|
||||||
|
public abstract double price();
|
||||||
@Override public String toString() {
|
@Override public String toString() {
|
||||||
// Print correct subclass name:
|
return String.format(
|
||||||
return getClass().getName() +
|
"%s weight: %.2f * price: %.2f = %.2f",
|
||||||
" w:" + weight() + " v:" +
|
getClass().getSimpleName(),
|
||||||
String.format("%.2f", value());
|
weight, price(), weight * price());
|
||||||
}
|
|
||||||
// Remainder of class supports dynamic creation:
|
|
||||||
public static class CannotCreateTrashException
|
|
||||||
extends RuntimeException {
|
|
||||||
public CannotCreateTrashException(Exception why) {
|
|
||||||
super(why);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static class TrashClassNotFoundException
|
|
||||||
extends RuntimeException {
|
|
||||||
public TrashClassNotFoundException(Exception why) {
|
|
||||||
super(why);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static class Info {
|
|
||||||
public String id;
|
|
||||||
public double data;
|
|
||||||
public Info(String name, double data) {
|
|
||||||
id = name;
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static List<Class> trashTypes =
|
|
||||||
new ArrayList<>();
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <T extends Trash> T factory(Info info) {
|
|
||||||
for(Class trashType : trashTypes) {
|
|
||||||
// Determine the type and create one:
|
|
||||||
if(trashType.getName().contains(info.id)) {
|
|
||||||
try {
|
|
||||||
// Get the dynamic constructor method
|
|
||||||
// that takes a double argument:
|
|
||||||
Constructor ctor =
|
|
||||||
trashType.getConstructor(double.class);
|
|
||||||
// Call the constructor to create a
|
|
||||||
// new object:
|
|
||||||
return
|
|
||||||
(T)ctor.newInstance(info.data);
|
|
||||||
} catch(Exception e) {
|
|
||||||
throw new CannotCreateTrashException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// The necessary Class was not in the list. Try to
|
|
||||||
// load it, but it must be in your class path!
|
|
||||||
try {
|
|
||||||
System.out.println("Loading " + info.id);
|
|
||||||
trashTypes.add(Class.forName(info.id));
|
|
||||||
} catch(Exception e) {
|
|
||||||
throw new TrashClassNotFoundException(e);
|
|
||||||
}
|
|
||||||
// Loaded successfully. Recursive call
|
|
||||||
// should work this time:
|
|
||||||
return factory(info);
|
|
||||||
}
|
}
|
||||||
|
// Ignore for now; to be used later:
|
||||||
|
public abstract void accept(Visitor v);
|
||||||
}
|
}
|
||||||
|
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
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Demonstration of "visitor" pattern
|
// Demonstration of the Visitor pattern.
|
||||||
// {java patterns.visitor.BeeAndFlowers}
|
// {java patterns.visitor.BeeAndFlowers}
|
||||||
package patterns.visitor;
|
package patterns.visitor;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -11,7 +11,7 @@ import java.util.stream.*;
|
|||||||
|
|
||||||
interface Visitor {
|
interface Visitor {
|
||||||
void visit(Gladiolus g);
|
void visit(Gladiolus g);
|
||||||
void visit(Renuculus r);
|
void visit(Ranunculus r);
|
||||||
void visit(Chrysanthemum c);
|
void visit(Chrysanthemum c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ class Gladiolus implements Flower {
|
|||||||
public void accept(Visitor v) { v.visit(this);}
|
public void accept(Visitor v) { v.visit(this);}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Renuculus implements Flower {
|
class Ranunculus implements Flower {
|
||||||
@Override
|
@Override
|
||||||
public void accept(Visitor v) { v.visit(this);}
|
public void accept(Visitor v) { v.visit(this);}
|
||||||
}
|
}
|
||||||
@ -37,13 +37,13 @@ class Chrysanthemum implements Flower {
|
|||||||
|
|
||||||
// Add the ability to produce a String:
|
// Add the ability to produce a String:
|
||||||
class StringVal implements Visitor {
|
class StringVal implements Visitor {
|
||||||
String s;
|
private String s;
|
||||||
@Override public String toString() { return s; }
|
@Override public String toString() { return s; }
|
||||||
@Override public void visit(Gladiolus g) {
|
@Override public void visit(Gladiolus g) {
|
||||||
s = "Gladiolus";
|
s = "Gladiolus";
|
||||||
}
|
}
|
||||||
@Override public void visit(Renuculus r) {
|
@Override public void visit(Ranunculus r) {
|
||||||
s = "Renuculus";
|
s = "Ranunculus";
|
||||||
}
|
}
|
||||||
@Override public void visit(Chrysanthemum c) {
|
@Override public void visit(Chrysanthemum c) {
|
||||||
s = "Chrysanthemum";
|
s = "Chrysanthemum";
|
||||||
@ -55,8 +55,8 @@ class Bee implements Visitor {
|
|||||||
@Override public void visit(Gladiolus g) {
|
@Override public void visit(Gladiolus g) {
|
||||||
System.out.println("Bee and Gladiolus");
|
System.out.println("Bee and Gladiolus");
|
||||||
}
|
}
|
||||||
@Override public void visit(Renuculus r) {
|
@Override public void visit(Ranunculus r) {
|
||||||
System.out.println("Bee and Renuculus");
|
System.out.println("Bee and Ranunculus");
|
||||||
}
|
}
|
||||||
@Override public void visit(Chrysanthemum c) {
|
@Override public void visit(Chrysanthemum c) {
|
||||||
System.out.println("Bee and Chrysanthemum");
|
System.out.println("Bee and Chrysanthemum");
|
||||||
@ -66,7 +66,7 @@ class Bee implements Visitor {
|
|||||||
class FlowerFactory {
|
class FlowerFactory {
|
||||||
static List<Supplier<Flower>> flowers =
|
static List<Supplier<Flower>> flowers =
|
||||||
Arrays.asList(Gladiolus::new,
|
Arrays.asList(Gladiolus::new,
|
||||||
Renuculus::new, Chrysanthemum::new);
|
Ranunculus::new, Chrysanthemum::new);
|
||||||
static final int SZ = flowers.size();
|
static final int SZ = flowers.size();
|
||||||
private static SplittableRandom rand =
|
private static SplittableRandom rand =
|
||||||
new SplittableRandom(47);
|
new SplittableRandom(47);
|
||||||
@ -95,21 +95,21 @@ public class BeeAndFlowers {
|
|||||||
Gladiolus
|
Gladiolus
|
||||||
Chrysanthemum
|
Chrysanthemum
|
||||||
Gladiolus
|
Gladiolus
|
||||||
Renuculus
|
Ranunculus
|
||||||
Chrysanthemum
|
Chrysanthemum
|
||||||
Renuculus
|
Ranunculus
|
||||||
Chrysanthemum
|
Chrysanthemum
|
||||||
Chrysanthemum
|
Chrysanthemum
|
||||||
Chrysanthemum
|
Chrysanthemum
|
||||||
Renuculus
|
Ranunculus
|
||||||
Bee and Gladiolus
|
Bee and Gladiolus
|
||||||
Bee and Chrysanthemum
|
Bee and Chrysanthemum
|
||||||
Bee and Gladiolus
|
Bee and Gladiolus
|
||||||
Bee and Renuculus
|
Bee and Ranunculus
|
||||||
Bee and Chrysanthemum
|
Bee and Chrysanthemum
|
||||||
Bee and Renuculus
|
Bee and Ranunculus
|
||||||
Bee and Chrysanthemum
|
Bee and Chrysanthemum
|
||||||
Bee and Chrysanthemum
|
Bee and Chrysanthemum
|
||||||
Bee and Chrysanthemum
|
Bee and Chrysanthemum
|
||||||
Bee and Renuculus
|
Bee and Ranunculus
|
||||||
*/
|
*/
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
// polymorphism/RTTI.java
|
// polymorphism/Reflect.java
|
||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Downcasting & Runtime type information (RTTI)
|
|
||||||
// {ThrowsException}
|
// {ThrowsException}
|
||||||
|
|
||||||
class Useful {
|
class Useful {
|
||||||
@ -18,7 +17,7 @@ class MoreUseful extends Useful {
|
|||||||
public void w() {}
|
public void w() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RTTI {
|
public class Reflect {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Useful[] x = {
|
Useful[] x = {
|
||||||
new Useful(),
|
new Useful(),
|
||||||
@ -28,7 +27,7 @@ public class RTTI {
|
|||||||
x[1].g();
|
x[1].g();
|
||||||
// Compile time: method not found in Useful:
|
// Compile time: method not found in Useful:
|
||||||
//- x[1].u();
|
//- x[1].u();
|
||||||
((MoreUseful)x[1]).u(); // Downcast/RTTI
|
((MoreUseful)x[1]).u(); // Downcast/Reflect
|
||||||
((MoreUseful)x[0]).u(); // Exception thrown
|
((MoreUseful)x[0]).u(); // Exception thrown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,5 +36,5 @@ ___[ Error Output ]___
|
|||||||
Exception in thread "main"
|
Exception in thread "main"
|
||||||
java.lang.ClassCastException: Useful cannot be cast to
|
java.lang.ClassCastException: Useful cannot be cast to
|
||||||
MoreUseful
|
MoreUseful
|
||||||
at RTTI.main(RTTI.java:29)
|
at Reflect.main(Reflect.java:28)
|
||||||
*/
|
*/
|
@ -13,7 +13,7 @@ class FruitQualities {
|
|||||||
private int ripeness;
|
private int ripeness;
|
||||||
private int smell;
|
private int smell;
|
||||||
// etc.
|
// etc.
|
||||||
// No-arg constructor:
|
// Zero-argument constructor:
|
||||||
FruitQualities() {
|
FruitQualities() {
|
||||||
// Do something meaningful...
|
// Do something meaningful...
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ class FruitQualities {
|
|||||||
|
|
||||||
class Seed {
|
class Seed {
|
||||||
// Members...
|
// Members...
|
||||||
Seed() { /* No-arg constructor */ }
|
Seed() { /* Zero-argument constructor */ }
|
||||||
Seed(Seed s) { /* Copy constructor */ }
|
Seed(Seed s) { /* Copy constructor */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ class Tomato extends Fruit {
|
|||||||
|
|
||||||
class ZebraQualities extends FruitQualities {
|
class ZebraQualities extends FruitQualities {
|
||||||
private int stripedness;
|
private int stripedness;
|
||||||
// No-arg constructor:
|
// Zero-argument constructor:
|
||||||
ZebraQualities() {
|
ZebraQualities() {
|
||||||
super();
|
super();
|
||||||
// do something meaningful...
|
// do something meaningful...
|
||||||
@ -117,7 +117,7 @@ public class CopyConstructor {
|
|||||||
t.getClass().getName());
|
t.getClass().getName());
|
||||||
}
|
}
|
||||||
public static void slice(Fruit f) {
|
public static void slice(Fruit f) {
|
||||||
f = new Fruit(f); // Hmmm... will this work? // [2]
|
f = new Fruit(f); // Hmm... will this work? // [2]
|
||||||
System.out.println("In slice, f is a " +
|
System.out.println("In slice, f is a " +
|
||||||
f.getClass().getName());
|
f.getClass().getName());
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
// typeinfo/AnonymousImplementation.java
|
// reflection/AnonymousImplementation.java
|
||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
||||||
// Anonymous inner classes can't hide from reflection
|
// Anonymous inner classes can't hide from reflection
|
||||||
import typeinfo.interfacea.*;
|
import reflection.interfacea.*;
|
||||||
|
|
||||||
class AnonymousA {
|
class AnonymousA {
|
||||||
public static A makeA() {
|
public static A makeA() {
|
@ -1,4 +1,4 @@
|
|||||||
// typeinfo/BoundedClassReferences.java
|
// reflection/BoundedClassReferences.java
|
||||||
// (c)2021 MindView LLC: see Copyright.txt
|
// (c)2021 MindView LLC: see Copyright.txt
|
||||||
// We make no guarantees that this code is fit for any purpose.
|
// We make no guarantees that this code is fit for any purpose.
|
||||||
// Visit http://OnJava8.com for more book information.
|
// Visit http://OnJava8.com for more book information.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user