On page 200, the code can use boxed()
instead of the (somewhat mysterious) maptoObject(e -> e)
One should also reveal to the reader that we are computing perfect numbers
package chapter12; import org.junit.jupiter.api.Test; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.LongStream; public class Chapter12 { // Confusing code on page 200 // but with mapToObj(e -> e) replaced with boxed() private static List<Long> confusingCode(long number) { return LongStream.rangeClosed(1, number) .filter(i -> { //Bad Code, don't do this long factor = 0; for (int j = 1; j < i; j++) { if (i % j == 0) { factor += j; } } return factor == i; }) .boxed() .toList(); } // Confusing code on page 201 // but with mapToObj(e -> e) replaced with boxed() private static List<Long> refactoredConfusingCode(long number) { return LongStream.range(1, number) .filter(i -> LongStream.range(1, i) //Not good .filter(j -> i % j == 0) .sum() == i) .boxed() .toList(); } // Nonconfusing code on page 201, in two methods private static Long sumOfDivisors(long number) { return LongStream.range(1, number) .filter(i -> number % i == 0) .sum(); } // Create list of those x <= limit such that the sum of the divisors of x equals x // https://en.wikipedia.org/wiki/Perfect_number // https://oeis.org/A000396 private static List<Long> nonConfusingCode(long limit) { return LongStream.rangeClosed(1, limit) .filter(i -> sumOfDivisors(i) == i) .boxed() .toList(); } // A record to pass data along the stream private record InAndOut(Long in, List<Long> out) { public String toString() { return "f(" + in + ")=[" + out.stream().map(it -> Long.toString(it)).collect(Collectors.joining(",")) + "]"; } } private static String exerciseCode(Function<Long, List<Long>> f, List<Long> input) { return input.stream() .map(it -> new InAndOut(it, f.apply(it))) .map(InAndOut::toString) .collect(Collectors.joining(", ")); } @Test public void exerciseAllCode() { var input = List.of(0L, 1L, 2L, 10L, 13L, 100L, 1000L, 10000L); { String str = exerciseCode(Chapter12::confusingCode, input); System.out.println(str); } { String str = exerciseCode(Chapter12::refactoredConfusingCode, input); System.out.println(str); } { String str = exerciseCode(Chapter12::nonConfusingCode, input); System.out.println(str); } } }