11. Streams
11.1. Integer streams
1import java.util.concurrent.ThreadLocalRandom;
2import java.util.stream.DoubleStream;
3import java.util.stream.IntStream;
4import java.util.stream.LongStream;
5import java.util.stream.Stream;
1// create stream of numbers: 1, 2, 3
2IntStream a = IntStream.range(1, 4);
3
4// create stream of numbers: 1, 2, 3, 4
5IntStream b = IntStream.rangeClosed(1, 4);
6
7// create stream of even numbers endlessly
8IntStream c = IntStream.iterate(0, n -> n + 2);
9
10// create stream of even numbers and take only 3
11IntStream d = IntStream.iterate(0, n -> n + 2)
12 .limit(3);
13
14// generate random numbers
15IntStream e = IntStream.generate(() -> ThreadLocalRandom.current().nextInt(10))
16 .limit(3);
17
18// mapping integers in stream to double their values
19IntStream f = IntStream.range(1, 5)
20 .map(n -> n * 2);
21
22// mapping integers to strings
23Stream<String> g = IntStream.range(1, 5)
24 .mapToObj(n -> String.valueOf(n));
25
26// mapping integers to longs
27LongStream h = IntStream.range(1, 5).mapToLong(n -> n);
28Stream<Long> i = IntStream.range(1, 5)
29 .mapToLong(n -> n)
30 .boxed();
31
32// mapping integers to doubles
33DoubleStream j = IntStream.range(1, 5).mapToDouble(n -> n);
34Stream<Double> k = IntStream.range(1, 5)
35 .mapToDouble(n -> n)
36 .boxed();
37
38// matching, check if there's at least 1 even number
39boolean l = IntStream.range(1, 5).anyMatch(n -> n % 2 == 0);
40
41// matching, check if all numbers are even
42boolean m = IntStream.range(1, 5).allMatch(n -> n % 2 == 0);
43
44// no matches, check if all numbers do not match
45boolean o = IntStream.range(1, 5).noneMatch(n -> n % 2 == 0);
46
47// get the min
48int p = IntStream.range(1, 5).min().getAsInt();
49
50// get the max
51int q = IntStream.range(1, 5).max().getAsInt();
52
53// do a count, note a long is returned
54long r = IntStream.range(1, 5).count();
55
56// get the average
57double s = IntStream.range(1, 5).average().getAsDouble();
58
59// get all the distinct elements
60IntStream t = IntStream.of(1, 2, 1, 1, 3, 4, 5).distinct();
11.2. Map, filter, reduce
11.2.1. Map, filter, reduce on list
1import java.util.Arrays;
2import java.util.List;
3import java.util.Optional;
1List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
2
3Optional<Integer> result = numbers.stream()
4 .map(num -> num * 2)
5 .filter(num -> num % 2 == 0)
6 .reduce((a, b) -> a + b);
7
8System.out.println(result.get());
11.2.2. Map, filter, reduce on integer stream
1import java.util.OptionalInt;
2import java.util.stream.IntStream;
1OptionalInt result = IntStream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
2 .map(num -> num * 2)
3 .filter(num -> num % 2 == 0)
4 .reduce((a, b) -> a + b);
5
6System.out.println(result.getAsInt());
11.2.3. Parallel map, filter, reduce
1import java.util.OptionalInt;
2import java.util.stream.IntStream;
1OptionalInt result = IntStream.range(1, 10000)
2 .parallel()
3 .map(num -> num * 2)
4 .filter(num -> num % 2 == 0)
5 .reduce((a, b) -> a + b);
6
7System.out.println(result.getAsInt());
11.3. Flat map
1import java.util.stream.Collectors;
2import java.util.stream.IntStream;
3import java.util.stream.Stream;
1String s = IntStream.rangeClosed(1, 5)
2 .flatMap(num -> IntStream.rangeClosed(-num, num))
3 .sorted()
4 .mapToObj(n -> String.valueOf(n))
5 .collect(Collectors.joining(","));
6
7System.out.println(s);
11.4. Collecting streams
1import java.util.Arrays;
2import java.util.List;
3import java.util.Map;
4import java.util.Set;
5import java.util.concurrent.ThreadLocalRandom;
6import java.util.stream.Collectors;
7import java.util.stream.IntStream;
1// collecting the stream to a list
2List<Integer> numberList = IntStream
3 .generate(() -> ThreadLocalRandom.current().nextInt(10))
4 .limit(100)
5 .boxed()
6 .collect(Collectors.toList());
7
8// collecting the stream to a set
9Set<Integer> numberSet = IntStream
10 .generate(() -> ThreadLocalRandom.current().nextInt(10))
11 .limit(100)
12 .boxed()
13 .collect(Collectors.toSet());
14
15// String concatenation again
16String s = Arrays.asList("John", "Jack", "Mary", "Nancy")
17 .stream()
18 .collect(Collectors.joining(","));
19
20// create a map; keys are names; values are length of names
21Map<String, Integer> m1 =
22 Arrays.asList("Jack", "John", "Jeremy", "Mary", "Nancy")
23 .stream()
24 .collect(Collectors.toMap(e -> e, e -> e.length()));
25
26// create a map; keys are length of names; values are list of names
27Map<Integer, List<String>> m2 =
28 Arrays.asList("Jack", "John", "Jeremy", "Mary", "Nancy")
29 .stream()
30 .collect(Collectors.groupingBy(
31 name -> name.length(),
32 Collectors.toList()
33 ));