Skip to content

Commit 1385436

Browse files
committed
Cleaned up Chapter 5 (Generics). Some examples were missing, some extraneous examples were present, and some page numbers were wrong.
1 parent 6d8f83c commit 1385436

21 files changed

+151
-77
lines changed

src/effectivejava/chapter5/item28/Chooser.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import java.util.Random;
77
import java.util.concurrent.ThreadLocalRandom;
88

9-
// List-based Chooser - typesafe (Page 120)
9+
// List-based Chooser - typesafe (Page 129)
1010
public class Chooser<T> {
1111
private final List<T> choiceList;
1212

@@ -18,4 +18,15 @@ public T choose() {
1818
Random rnd = ThreadLocalRandom.current();
1919
return choiceList.get(rnd.nextInt(choiceList.size()));
2020
}
21+
22+
public static void main(String[] args) {
23+
List<Integer> intList = List.of(1, 2, 3, 4, 5, 6);
24+
25+
Chooser<Integer> chooser = new Chooser<>(intList);
26+
27+
for (int i = 0; i < 10; i++) {
28+
Number choice = chooser.choose();
29+
System.out.println(choice);
30+
}
31+
}
2132
}

src/effectivejava/chapter5/item29/technqiue1/Stack.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import java.util.Arrays;
55

6-
// Generic stack using E[] - Pages 130-133
6+
// Generic stack using E[] (Pages 130-3)
77
public class Stack<E> {
88
private E[] elements;
99
private int size = 0;

src/effectivejava/chapter5/item29/technqiue2/Stack.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import java.util.Arrays;
44
import effectivejava.chapter5.item29.EmptyStackException;
55

6-
// Generic stack using Object[] - Pages 130-133
6+
// Generic stack using Object[] (Pages 130-3)
77
public class Stack<E> {
88
private Object[] elements;
99
private int size = 0;

src/effectivejava/chapter5/item30/GenericSingletonFactory.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package effectivejava.chapter5.item30;
22

3-
// Generic singleton factory staticfactory - Pages 131-132
4-
53
import java.util.function.UnaryOperator;
64

7-
// Generic singleton factory pattern (Page 136)
5+
// Generic singleton factory pattern (Page 136-7)
86
public class GenericSingletonFactory {
97
// Generic singleton factory pattern
108
private static UnaryOperator<Object> IDENTITY_FN = (t) -> t;

src/effectivejava/chapter5/item30/RecursiveTypeBound.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package effectivejava.chapter5.item30;
22
import java.util.*;
33

4-
// Using a recursive type bound to express mutual comparability - Pages 136-137
4+
// Using a recursive type bound to express mutual comparability (Pages 137-8)
55
public class RecursiveTypeBound {
66
// Returns max value in a collection - uses recursive type bound
77
public static <E extends Comparable<E>> E max(Collection<E> c) {

src/effectivejava/chapter5/item30/Union.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package effectivejava.chapter5.item30;
22
import java.util.*;
33

4-
// Generic union method and program to exercise it - pages 135-6
4+
// Generic union method and program to exercise it (Pages 135-6)
55
public class Union {
66

77
// Generic method

src/effectivejava/chapter5/item32/Chooser.java renamed to src/effectivejava/chapter5/item31/Chooser.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
package effectivejava.chapter5.item32;
1+
package effectivejava.chapter5.item31;
22

33
import java.util.ArrayList;
44
import java.util.Collection;
55
import java.util.List;
66
import java.util.Random;
77

8+
// Wildcard type for parameter that serves as an T producer (page 141)
89
public class Chooser<T> {
910
private final List<T> choiceList;
1011
private final Random rnd = new Random();
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package effectivejava.chapter5.item32;
1+
package effectivejava.chapter5.item31;
22

33
public class EmptyStackException extends RuntimeException {
44
}

src/effectivejava/chapter5/item32/RecursiveTypeBound.java renamed to src/effectivejava/chapter5/item31/RecursiveTypeBound.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
package effectivejava.chapter5.item32;
1+
package effectivejava.chapter5.item31;
22
import java.util.*;
33

4-
// Using a recursive type bound with wildcards - Page 138-139
4+
// Using a recursive type bound with wildcards (Page 143)
55
public class RecursiveTypeBound {
66
public static <E extends Comparable<? super E>> E max(
77
List<? extends E> list) {

src/effectivejava/chapter5/item32/Stack.java renamed to src/effectivejava/chapter5/item31/Stack.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
package effectivejava.chapter5.item32;
1+
package effectivejava.chapter5.item31;
22
import java.util.*;
33

4-
// Generic stack with bulk methods using wildcard types - Pages 138-140
4+
// Generic stack with bulk methods using wildcard types (Pages 139-41)
55
public class Stack<E> {
66
private E[] elements;
77
private int size = 0;
@@ -63,11 +63,11 @@ public void popAll(Collection<? super E> dst) {
6363

6464
// Little program to exercise our generic Stack
6565
public static void main(String[] args) {
66-
Stack<Number> numberStack = new Stack<Number>();
66+
Stack<Number> numberStack = new Stack<>();
6767
Iterable<Integer> integers = Arrays.asList(3, 1, 4, 1, 5, 9);
6868
numberStack.pushAll(integers);
6969

70-
Collection<Object> objects = new ArrayList<Object>();
70+
Collection<Object> objects = new ArrayList<>();
7171
numberStack.popAll(objects);
7272

7373
System.out.println(objects);

src/effectivejava/chapter5/item32/Swap.java renamed to src/effectivejava/chapter5/item31/Swap.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
package effectivejava.chapter5.item32;
1+
package effectivejava.chapter5.item31;
22
import java.util.*;
33

4-
// Private helper staticfactory for wildcard capture - Pages 139-140
4+
// Private helper method for wildcard capture (Page 145)
55
public class Swap {
66
public static void swap(List<?> list, int i, int j) {
77
swapHelper(list, i, j);
88
}
99

10-
// Private helper staticfactory for wildcard capture
10+
// Private helper method for wildcard capture
1111
private static <E> void swapHelper(List<E> list, int i, int j) {
1212
list.set(i, list.set(j, list.get(i)));
1313
}

src/effectivejava/chapter5/item32/Union.java renamed to src/effectivejava/chapter5/item31/Union.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
package effectivejava.chapter5.item32;
1+
package effectivejava.chapter5.item31;
22
import java.util.*;
33

4-
// Generic union staticfactory with wildcard types - Pages 137-138
4+
// Generic union method with wildcard types for enhanced flexibility (Pages 142-3)
55
public class Union {
6-
76
public static <E> Set<E> union(Set<? extends E> s1,
87
Set<? extends E> s2) {
98
Set<E> result = new HashSet<E>(s1);
@@ -25,6 +24,9 @@ public static void main(String[] args) {
2524

2625
Set<Number> numbers = union(integers, doubles);
2726

27+
// // Explicit type parameter - required prior to Java 8
28+
// Set<Number> numbers = Union.<Number>union(integers, doubles);
29+
2830
System.out.println(numbers);
2931
}
3032
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package effectivejava.chapter5.item32;
2+
3+
import java.util.List;
4+
5+
// It is unsafe to store a value in a generic varargs array parameter (Page 146)
6+
public class Dangerous {
7+
// Mixing generics and varargs can violate type safety!
8+
static void dangerous(List<String>... stringLists) {
9+
List<Integer> intList = List.of(42);
10+
Object[] objects = stringLists;
11+
objects[0] = intList; // Heap pollution
12+
String s = stringLists[0].get(0); // ClassCastException
13+
}
14+
15+
public static void main(String[] args) {
16+
dangerous(List.of("There be dragons!"));
17+
}
18+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package effectivejava.chapter5.item32;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
// List as a typesafe alternative to a generic varargs parameter (page 149)
7+
public class FlattenWithList {
8+
static <T> List<T> flatten(List<List<? extends T>> lists) {
9+
List<T> result = new ArrayList<>();
10+
for (List<? extends T> list : lists)
11+
result.addAll(list);
12+
return result;
13+
}
14+
15+
public static void main(String[] args) {
16+
List<Integer> flatList = flatten(List.of(
17+
List.of(1, 2), List.of(3, 4, 5), List.of(6,7)));
18+
System.out.println(flatList);
19+
}
20+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package effectivejava.chapter5.item32;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
// Safe method with a generic varargs parameter (page 149)
7+
public class FlattenWithVarargs {
8+
@SafeVarargs
9+
static <T> List<T> flatten(List<? extends T>... lists) {
10+
List<T> result = new ArrayList<>();
11+
for (List<? extends T> list : lists)
12+
result.addAll(list);
13+
return result;
14+
}
15+
16+
public static void main(String[] args) {
17+
List<Integer> flatList = flatten(
18+
List.of(1, 2), List.of(3, 4, 5), List.of(6,7));
19+
System.out.println(flatList);
20+
}
21+
}

src/effectivejava/chapter5/item32/Function.java

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package effectivejava.chapter5.item32;
2+
3+
import java.util.Arrays;
4+
import java.util.concurrent.ThreadLocalRandom;
5+
6+
// Subtle heap pollution (Pages 147-8)
7+
public class PickTwo {
8+
// UNSAFE - Exposes a reference to its generic parameter array!
9+
static <T> T[] toArray(T... args) {
10+
return args;
11+
}
12+
13+
static <T> T[] pickTwo(T a, T b, T c) {
14+
switch(ThreadLocalRandom.current().nextInt(3)) {
15+
case 0: return toArray(a, b);
16+
case 1: return toArray(a, c);
17+
case 2: return toArray(b, c);
18+
}
19+
throw new AssertionError(); // Can't get here
20+
}
21+
22+
public static void main(String[] args) {
23+
String[] attributes = pickTwo("Good", "Fast", "Cheap");
24+
System.out.println(Arrays.toString(attributes));
25+
}
26+
}

src/effectivejava/chapter5/item32/Reduction.java

Lines changed: 0 additions & 36 deletions
This file was deleted.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package effectivejava.chapter5.item32;
2+
3+
import java.util.Arrays;
4+
import java.util.List;
5+
import java.util.concurrent.ThreadLocalRandom;
6+
7+
// Safe version of PickTwo using lists instead of arrays (Page 150)
8+
public class SafePickTwo {
9+
static <T> List<T> pickTwo(T a, T b, T c) {
10+
switch(ThreadLocalRandom.current().nextInt(3)) {
11+
case 0: return List.of(a, b);
12+
case 1: return List.of(a, c);
13+
case 2: return List.of(b, c);
14+
}
15+
throw new AssertionError();
16+
}
17+
18+
public static void main(String[] args) {
19+
List<String> attributes = pickTwo("Good", "Fast", "Cheap");
20+
System.out.println(attributes);
21+
}
22+
}
Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,32 @@
11
package effectivejava.chapter5.item33;
22
import java.util.*;
33

4-
// Typesafe heterogeneous container - Pages 142-145
4+
// Typesafe heterogeneous container pattern (Pages 151-4)
55
public class Favorites {
6-
// Typesafe heterogeneous container pattern - implementation
7-
private Map<Class<?>, Object> favorites =
8-
new HashMap<Class<?>, Object>();
6+
private Map<Class<?>, Object> favorites = new HashMap<>();
97

108
public <T> void putFavorite(Class<T> type, T instance) {
11-
if (type == null)
12-
throw new NullPointerException("LifeCycle is null");
13-
favorites.put(type, instance);
9+
favorites.put(Objects.requireNonNull(type), instance);
1410
}
1511

1612
public <T> T getFavorite(Class<T> type) {
1713
return type.cast(favorites.get(type));
1814
}
1915

16+
// // Achieving runtime type safety with a dynamic cast
17+
// public <T> void putFavorite(Class<T> type, T instance) {
18+
// favorites.put(Objects.requireNonNull(type), type.cast(instance));
19+
// }
2020

21-
// Typesafe heterogeneous container pattern - client
2221
public static void main(String[] args) {
2322
Favorites f = new Favorites();
2423
f.putFavorite(String.class, "Java");
2524
f.putFavorite(Integer.class, 0xcafebabe);
2625
f.putFavorite(Class.class, Favorites.class);
27-
2826
String favoriteString = f.getFavorite(String.class);
2927
int favoriteInteger = f.getFavorite(Integer.class);
3028
Class<?> favoriteClass = f.getFavorite(Class.class);
3129
System.out.printf("%s %x %s%n", favoriteString,
32-
favoriteInteger, favoriteClass.getName());
30+
favoriteInteger, favoriteClass.getName());
3331
}
3432
}

src/effectivejava/chapter5/item33/PrintAnnotation.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
import java.lang.annotation.*;
33
import java.lang.reflect.*;
44

5-
// Use of asSubclass to safely cast to a bounded type token - Page 146
5+
// Use of asSubclass to safely cast to a bounded type token (Page 155)
66
public class PrintAnnotation {
7-
// Use of asSubclass to safely cast to a bounded type token
87
static Annotation getAnnotation(AnnotatedElement element,
98
String annotationTypeName) {
109
Class<?> annotationType = null; // Unbounded type token
@@ -14,7 +13,7 @@ static Annotation getAnnotation(AnnotatedElement element,
1413
throw new IllegalArgumentException(ex);
1514
}
1615
return element.getAnnotation(
17-
annotationType.asSubclass(Annotation.class));
16+
annotationType.asSubclass(Annotation.class));
1817
}
1918

2019
// Test program to print named annotation of named class

0 commit comments

Comments
 (0)