Skip to content

Commit c641e58

Browse files
committed
Clean up code examples from Chapter 7 (Lambdas and Streams)
1 parent d2cf57e commit c641e58

File tree

16 files changed

+77
-42
lines changed

16 files changed

+77
-42
lines changed

src/effectivejava/chapter6/item34/Operation.java

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

55
import static java.util.stream.Collectors.toMap;
66

7-
// Enum type with constant-specific class bodies and data (Page 163-4)
7+
// Enum type with constant-specific class bodies and data (Pages 163-4)
88
public enum Operation {
99
PLUS("+") {
1010
public double apply(double x, double y) { return x + y; }

src/effectivejava/chapter7/item42/Operation.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import java.util.function.DoubleBinaryOperator;
44

5-
// Enum with function object fields & constant-specific behavior
5+
// Enum with function object fields & constant-specific behavior (Page 195)
66
public enum Operation {
77
PLUS ("+", (x, y) -> x + y),
88
MINUS ("-", (x, y) -> x - y),
@@ -22,4 +22,13 @@ public enum Operation {
2222
public double apply(double x, double y) {
2323
return op.applyAsDouble(x, y);
2424
}
25+
26+
// Main method from Item 34 (Page 163)
27+
public static void main(String[] args) {
28+
double x = Double.parseDouble(args[0]);
29+
double y = Double.parseDouble(args[1]);
30+
for (Operation op : Operation.values())
31+
System.out.printf("%f %s %f = %f%n",
32+
x, op, y, op.apply(x, y));
33+
}
2534
}

src/effectivejava/chapter7/item42/SortFourWays.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88

99
import static java.util.Comparator.comparingInt;
1010

11+
// Sorting with function objects (Pages 193-4)
1112
public class SortFourWays {
1213
public static void main(String[] args) {
1314
List<String> words = Arrays.asList(args);
1415

15-
// Anonymous class instance as a function object - obsolete!
16+
// Anonymous class instance as a function object - obsolete! (Page 193)
1617
Collections.sort(words, new Comparator<String>() {
1718
public int compare(String s1, String s2) {
1819
return Integer.compare(s1.length(), s2.length());
@@ -21,16 +22,18 @@ public int compare(String s1, String s2) {
2122
System.out.println(words);
2223
Collections.shuffle(words);
2324

24-
// Lambda expression as function object (replaces anonymous class)
25+
// Lambda expression as function object (replaces anonymous class) (Page 194)
2526
Collections.sort(words,
2627
(s1, s2) -> Integer.compare(s1.length(), s2.length()));
2728
System.out.println(words);
2829
Collections.shuffle(words);
2930

31+
// Comparator construction method (with method reference) in place of lambda (Page 194)
3032
Collections.sort(words, comparingInt(String::length));
3133
System.out.println(words);
3234
Collections.shuffle(words);
3335

36+
// Default method List.sort in conjunction with comparator construction method (Page 194)
3437
words.sort(comparingInt(String::length));
3538
System.out.println(words);
3639
}

src/effectivejava/chapter7/item43/Freq.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33
import java.util.Map;
44
import java.util.TreeMap;
55

6-
// p. 197
6+
// Frequency table implemented with map.merge, using lambda and method reference (Page 197)
77
public class Freq {
88
public static void main(String[] args) {
99
Map<String, Integer> frequencyTable = new TreeMap<>();
10-
for (String s : args) {
11-
// map.merge(key, 1, (count, incr) -> count + incr);
12-
frequencyTable.merge(s, 1, Integer::sum);
13-
}
10+
11+
for (String s : args)
12+
frequencyTable.merge(s, 1, (count, incr) -> count + incr); // Lambda
13+
System.out.println(frequencyTable);
1414

15+
frequencyTable.clear();
16+
for (String s : args)
17+
frequencyTable.merge(s, 1, Integer::sum); // Method reference
1518
System.out.println(frequencyTable);
19+
1620
}
1721
}

src/effectivejava/chapter7/item45/Card.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
import java.util.stream.Stream;
66
import static java.util.stream.Collectors.*;
77

8+
// Generating the Cartesian product of two lists using iteration and streams (Page 209)
89
public class Card {
910
public enum Suit { SPADE, HEART, DIAMOND, CLUB }
1011
public enum Rank { ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN,
11-
EIGHT, NINE, TEN, JACK, KING, QUEEN }
12+
EIGHT, NINE, TEN, JACK, QUEEN, KING }
1213

1314
private final Suit suit;
1415
private final Rank rank;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package effectivejava.chapter7.item45;
2+
3+
// Refrain from using streams to process char values (Page 206)
4+
public class CharStream {
5+
public static void main(String[] args) {
6+
// Does not produce the expected result
7+
"Hello world!".chars().forEach(System.out::print);
8+
System.out.println();
9+
10+
// Fixes the problem
11+
"Hello world!".chars().forEach(x -> System.out.print((char) x));
12+
System.out.println();
13+
}
14+
}

src/effectivejava/chapter7/item45/MersennePrimes.java

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

66
import static java.math.BigInteger.*;
77

8-
// P. 208
8+
// Generating the first twent Mersenne primes using streams (Page 208)
99
public class MersennePrimes {
1010
static Stream<BigInteger> primes() {
1111
return Stream.iterate(TWO, BigInteger::nextProbablePrime);

src/effectivejava/chapter7/item45/anagrams/HybridAnagrams.java

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

1010
import static java.util.stream.Collectors.groupingBy;
1111

12-
// Tasteful use of streams enhances clarity and conciseness
12+
// Tasteful use of streams enhances clarity and conciseness (Page 205)
1313
public class HybridAnagrams {
1414
public static void main(String[] args) throws IOException {
1515
Path dictionary = Paths.get(args[0]);

src/effectivejava/chapter7/item45/anagrams/IterativeAnagrams.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import java.io.IOException;
55
import java.util.*;
66

7-
// Prints all large anagram groups in a dictionary iteratively
7+
// Prints all large anagram groups in a dictionary iteratively (Page 204)
88
public class IterativeAnagrams {
99
public static void main(String[] args) throws IOException {
1010
File dictionary = new File(args[0]);

src/effectivejava/chapter7/item45/anagrams/StreamAnagrams.java

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

99
import static java.util.stream.Collectors.groupingBy;
1010

11-
// Overuse of streams - don't do this! - (page 205)
11+
// Overuse of streams - don't do this! (page 205)
1212
public class StreamAnagrams {
1313
public static void main(String[] args) throws IOException {
1414
Path dictionary = Paths.get(args[0]);

src/effectivejava/chapter7/item45/Freq.java renamed to src/effectivejava/chapter7/item46/Freq.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package effectivejava.chapter7.item45;
1+
package effectivejava.chapter7.item46;
22

33
import java.io.File;
44
import java.io.FileNotFoundException;
@@ -9,20 +9,20 @@
99
import static java.util.stream.Collectors.*;
1010
import static java.util.stream.Collectors.*;
1111

12-
// Page 210, 211
12+
// Frequency table examples showing improper and proper use of stream (Page 210-11)
1313
public class Freq {
1414
public static void main(String[] args) throws FileNotFoundException {
1515
File file = new File(args[0]);
1616

17-
// Uses the streams API but not the paradigm--Don't do this!
17+
// // Uses the streams API but not the paradigm--Don't do this!
1818
// Map<String, Long> freq = new HashMap<>();
1919
// try (Stream<String> words = new Scanner(file).tokens()) {
2020
// words.forEach(word -> {
2121
// freq.merge(word.toLowerCase(), 1L, Long::sum);
2222
// });
2323
// }
2424

25-
// Proper use of streams to initialize a frequency table
25+
// Proper use of streams to initialize a frequency table (
2626
Map<String, Long> freq;
2727
try (Stream<String> words = new Scanner(file).tokens()) {
2828
freq = words

src/effectivejava/chapter7/item47/Adapters.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
import java.util.stream.Stream;
44
import java.util.stream.StreamSupport;
55

6+
// Adapters from stream to iterable and vice-versa (Page 216)
67
public class Adapters {
7-
// Adapter from Stream<E> to Iterable<E>
8+
// Adapter from Stream<E> to Iterable<E> (
89
public static <E> Iterable<E> iterableOf(Stream<E> stream) {
910
return stream::iterator;
1011
}

src/effectivejava/chapter7/item47/PowerSet.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.*;
44

55
public class PowerSet {
6+
// Returns the power set of an input set as custom collection (Page 218)
67
public static final <E> Collection<Set<E>> of(Set<E> s) {
78
List<E> src = new ArrayList<>(s);
89
if (src.size() > 30)

src/effectivejava/chapter7/item47/SubLists.java

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,34 @@
44
import java.util.stream.IntStream;
55
import java.util.stream.Stream;
66

7-
// Returns a stream of all the sublists of its input list (Pages 219-220)
7+
// Two ways to generate a stream of all the sublists of a list (Pages 219-20)
88
public class SubLists {
9-
// public static <E> Stream<List<E>> of(List<E> list) {
10-
// return Stream.concat(Stream.of(Collections.emptyList()),
11-
// prefixes(list).flatMap(SubLists::suffixes));
12-
// }
13-
//
14-
// private static <E> Stream<List<E>> prefixes(List<E> list) {
15-
// return IntStream.rangeClosed(1, list.size())
16-
// .mapToObj(end -> list.subList(0, end));
17-
// }
18-
//
19-
// private static <E> Stream<List<E>> suffixes(List<E> list) {
20-
// return IntStream.range(0, list.size())
21-
// .mapToObj(start -> list.subList(start, list.size()));
22-
// }
23-
24-
// Returns a stream of all the sublists of its input list
9+
// Returns a stream of all the sublists of its input list (Page 219)
2510
public static <E> Stream<List<E>> of(List<E> list) {
11+
return Stream.concat(Stream.of(Collections.emptyList()),
12+
prefixes(list).flatMap(SubLists::suffixes));
13+
}
14+
15+
private static <E> Stream<List<E>> prefixes(List<E> list) {
16+
return IntStream.rangeClosed(1, list.size())
17+
.mapToObj(end -> list.subList(0, end));
18+
}
19+
20+
private static <E> Stream<List<E>> suffixes(List<E> list) {
2621
return IntStream.range(0, list.size())
27-
.mapToObj(start ->
28-
IntStream.rangeClosed(start + 1, list.size())
29-
.mapToObj(end -> list.subList(start, end)))
30-
.flatMap(x -> x);
22+
.mapToObj(start -> list.subList(start, list.size()));
3123
}
3224

25+
// // Returns a stream of all the sublists of its input list, excluding the empty list
26+
// // This version is derived from the obvious iterative code (Page 220)
27+
// public static <E> Stream<List<E>> of(List<E> list) {
28+
// return IntStream.range(0, list.size())
29+
// .mapToObj(start ->
30+
// IntStream.rangeClosed(start + 1, list.size())
31+
// .mapToObj(end -> list.subList(start, end)))
32+
// .flatMap(x -> x);
33+
// }
34+
3335
public static void main(String[] args) {
3436
List<String> list = Arrays.asList(args);
3537
SubLists.of(list).forEach(System.out::println);

src/effectivejava/chapter7/item48/ParallelMersennePrimes.java

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

66
import static java.math.BigInteger.*;
77

8-
// Parallel stream-based program to generate the first 20 Mersenne primes - HANGS!!!
8+
// Parallel stream-based program to generate the first 20 Mersenne primes - HANGS!!! (Page 222)
99
public class ParallelMersennePrimes {
1010
public static void main(String[] args) {
1111
primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE))

src/effectivejava/chapter7/item48/ParallelPrimeCounting.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import java.util.stream.LongStream;
55

66
public class ParallelPrimeCounting {
7-
// Prime-counting stream pipeline - parallel version
7+
// Prime-counting stream pipeline - parallel version (Page 225)
88
static long pi(long n) {
99
return LongStream.rangeClosed(2, n)
1010
.parallel()

0 commit comments

Comments
 (0)