weird stream api
TRANSCRIPT
![Page 1: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/1.jpg)
Weird Stream API
Тагир ВалеевJetBrains
![Page 3: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/3.jpg)
3
Почему мне можно верить?• JDK-8072727 Add variation of Stream.iterate() that's finite• JDK-8136686 Collectors.counting can use Collectors.summingLong to reduce boxing• JDK-8141630 Specification of Collections.synchronized* need to state traversal constraints• JDK-8145007 Pattern splitAsStream is not late binding as required by the specification• JDK-8146218 Add LocalDate.datesUntil method producing Stream<LocalDate>• JDK-8147505 BaseStream.onClose() should not allow registering new handlers after stream is consumed• JDK-8148115 Stream.findFirst for unordered source optimization• JDK-8148250 Stream.limit() parallel tasks with ordered non-SUBSIZED source should short-circuit• JDK-8148838 Stream.flatMap(...).spliterator() cannot properly split after tryAdvance()• JDK-8148748 ArrayList.subList().spliterator() is not late-binding• JDK-8151123 Collectors.summingDouble/averagingDouble unnecessarily call mapper twice• JDK-8153293 Preserve SORTED and DISTINCT characteristics for boxed() and asLongStream() operations• JDK-8154387 Parallel unordered Stream.limit() tries to collect 128 elements even if limit is less• JDK-8155600 Performance optimization of Arrays.asList().iterator()• JDK-8164189 Collectors.toSet() parallel performance improvement
![Page 4: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/4.jpg)
4
![Page 5: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/5.jpg)
5
![Page 6: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/6.jpg)
6
source.stream()
![Page 7: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/7.jpg)
7
.map(x -> x.squash())
![Page 8: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/8.jpg)
8
.filter(x -> x.getColor() != YELLOW)
![Page 9: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/9.jpg)
9
.forEach(System.out::println)
![Page 10: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/10.jpg)
10
source.stream() .map(x -> x.squash()) .filter(x -> x.getColor() != YELLOW) .forEach(System.out::println)
![Page 11: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/11.jpg)
11
AtomicLong cnt = new AtomicLong();
.peek(x -> cnt.incrementAndGet())
![Page 12: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/12.jpg)
12
AtomicLong cnt = new AtomicLong();
source.stream() .map(x -> x.squash()) .peek(x -> cnt.incrementAndGet()) .filter(x -> x.getColor() != YELLOW) .forEach(System.out::println)
![Page 13: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/13.jpg)
13
LongStream.range(1, 100) .count();
![Page 14: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/14.jpg)
14
LongStream.range(1, 100) .count();>> 99
![Page 15: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/15.jpg)
15
LongStream.range(0, 1_000_000_000_000_000_000L) .count();
![Page 16: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/16.jpg)
16
LongStream.range(0, 1_000_000_000_000_000_000L) .count();
![Page 17: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/17.jpg)
17
LongStream.range(0, 1_000_000_000_000_000_000L) .count();>> 1000000000000000000
Java 9:JDK-8067969 Optimize Stream.count for SIZED Streams
![Page 18: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/18.jpg)
18
public interface Spliterator<T> { boolean tryAdvance(Consumer<? super T> action); default void forEachRemaining(Consumer<? super T> action) { … }
Spliterator<T> trySplit();
long estimateSize(); default long getExactSizeIfKnown() { … }
int characteristics(); default boolean hasCharacteristics(int characteristics) { … }
default Comparator<? super T> getComparator() { … } …}
![Page 19: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/19.jpg)
19
Характеристики
SIZEDSUBSIZEDSORTEDORDERED
DISTINCTNONNULLIMMUTABLECONCURRENT
![Page 20: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/20.jpg)
20
list.stream() .peek(data -> process(data)) .peek(data -> processInAnotherWay(data)) .count(); // какая-нибудь терминальная операция
![Page 21: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/21.jpg)
21
Характеристики
SIZEDSUBSIZEDSORTEDORDERED
DISTINCTNONNULLIMMUTABLECONCURRENT
![Page 22: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/22.jpg)
22
Характеристики
SIZEDSUBSIZEDSORTEDORDERED
DISTINCTNONNULLIMMUTABLECONCURRENT
![Page 23: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/23.jpg)
23
Stream<T>IntStreamLongStreamDoubleStream
![Page 24: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/24.jpg)
24
Stream<T>IntStream Stream<Integer>
LongStream Stream<Long>DoubleStream Stream<Double>
![Page 25: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/25.jpg)
25
Primitive is faster!
![Page 26: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/26.jpg)
26
int[] ints;Integer[] integers;
@Setuppublic void setup() { ints = new Random(1).ints(1000000, 0, 1000) .toArray(); integers = new Random(1).ints(1000000, 0, 1000) .boxed().toArray(Integer[]::new);}
![Page 27: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/27.jpg)
27
@Benchmarkpublic long stream() { return Stream.of(integers).distinct().count();}
@Benchmarkpublic long intStream() { return IntStream.of(ints).distinct().count();}
![Page 28: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/28.jpg)
28
@Benchmarkpublic long stream() { return Stream.of(integers).distinct().count();}
@Benchmarkpublic long intStream() { return IntStream.of(ints).distinct().count();}
# VM version: JDK 1.8.0_92, VM 25.92-b14Benchmark Mode Cnt Score Error UnitsintStream avgt 30 17.121 ± 0.296 ms/opstream avgt 30 15.764 ± 0.116 ms/op
![Page 29: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/29.jpg)
29
Stream<T> ⇒ ReferencePipelineIntStream ⇒ IntPipelineLongStream ⇒ LongPipelineDoubleStream ⇒ DoublePipeline
AbstractPipeline
package java.util.stream;
![Page 30: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/30.jpg)
30
// java.util.stream.IntPipeline
@Overridepublic final IntStream distinct() { // While functional and quick to implement, // this approach is not very efficient. // An efficient version requires // an int-specific map/set implementation. return boxed().distinct().mapToInt(i -> i);}
![Page 31: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/31.jpg)
31
@Benchmarkpublic long stream() { return Stream.of(integers).distinct().count();}
@Benchmarkpublic long intStream() { // IntStream.of(ints).distinct().count(); return IntStream.of(ints).boxed().distinct() .mapToInt(i -> i).count();}
-prof gcstream 48870 B/opintStream 13642536 B/op
![Page 32: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/32.jpg)
32
Задача: вычислить сумму 5 различных псевдослучайных чисел от 1 до 20.
Image courtesy: http://magenta-stock.deviantart.com/
![Page 33: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/33.jpg)
33
Задача: вычислить сумму 5 различных псевдослучайных чисел от 1 до 20.
// IntStream ints(long streamSize, int origin, int bound)new Random().ints(5, 1, 20+1).sum();
![Page 34: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/34.jpg)
34
Задача: вычислить сумму 5 различных псевдослучайных чисел от 1 до 20.
// IntStream ints(long streamSize, int origin, int bound)new Random().ints(5, 1, 20+1).sum();
![Page 35: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/35.jpg)
35
Задача: вычислить сумму 5 различных псевдослучайных чисел от 1 до 20.
// IntStream ints(long streamSize, int origin, int bound)new Random().ints(5, 1, 20+1).sum();
new Random().ints(5, 1, 20+1).distinct().sum();
![Page 36: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/36.jpg)
36
Задача: вычислить сумму 5 различных псевдослучайных чисел от 1 до 20.
// IntStream ints(long streamSize, int origin, int bound)new Random().ints(5, 1, 20+1).sum();
new Random().ints(5, 1, 20+1).distinct().sum();
// IntStream ints(int origin, int bound)new Random().ints(1, 20+1).distinct().limit(5).sum();
…
![Page 37: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/37.jpg)
37
Задача: вычислить сумму 5 различных псевдослучайных чисел от 1 до 20.
new Random().ints(1, 20+1).distinct().limit(5).sum();
new Random().ints(1, 20+1).parallel().distinct().limit(5).sum();
new Random().ints(1, 20+1).distinct().parallel().limit(5).sum();
new Random().ints(1, 20+1).distinct().limit(5).parallel().sum();
![Page 38: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/38.jpg)
38
Задача: вычислить сумму 5 различных псевдослучайных чисел от 1 до 20.
new Random().ints(1, 20+1).distinct().limit(5).sum();
new Random().ints(1, 20+1).parallel().distinct().limit(5).sum();
new Random().ints(1, 20+1).distinct().parallel().limit(5).sum();
new Random().ints(1, 20+1).distinct().limit(5).parallel().sum();
new Random().ints(1, 20+1).parallel().distinct().limit(5) .sequential().sum();
JDK-8132800 clarify stream package documentation regarding sequential vs parallel modes
![Page 39: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/39.jpg)
39
Задача: вычислить сумму 5 различных псевдослучайных чисел от 1 до 20.
new Random().ints(1, 20+1).distinct().limit(5).sum();
# VM version: JDK 1.8.0_92, VM 25.92-b14Benchmark Mode Cnt Score Error UnitsrndSum avgt 30 0.286 ± 0.001 us/op
![Page 40: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/40.jpg)
40
Задача: вычислить сумму 5 различных псевдослучайных чисел от 1 до 20.
new Random().ints(1, 20+1).distinct().limit(5).sum();
# VM version: JDK 1.8.0_92, VM 25.92-b14Benchmark Mode Cnt Score Error UnitsrndSum avgt 30 0.286 ± 0.001 us/oprndSumPar ~6080 years/op
![Page 41: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/41.jpg)
41
Задача: вычислить сумму 5 различных псевдослучайных чисел от 1 до 20.
new Random().ints(1, 20+1).distinct().limit(5).sum();
# VM version: JDK 1.8.0_92, VM 25.92-b14Benchmark Mode Cnt Score Error UnitsrndSum avgt 30 0.286 ± 0.001 us/oprndSumPar ~6080 years/op
java.util.stream.StreamSpliterators.UnorderedSliceSpliterator<T, T_SPLITR>
![Page 42: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/42.jpg)
42
Задача: вычислить сумму 5 различных псевдослучайных чисел от 1 до 20.
public IntStream ints(int randomNumberOrigin, int randomNumberBound) Returns an effectively unlimited stream of pseudorandom int values, each conformingto the given origin (inclusive) and bound (exclusive).
Implementation Note:This method is implemented to be equivalent to ints(Long.MAX_VALUE, randomNumberOrigin, randomNumberBound).
![Page 43: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/43.jpg)
43
Задача: вычислить сумму 5 различных псевдослучайных чисел от 1 до 20.
new Random().ints(1, 20+1).distinct().limit(5).sum();new Random().ints(1, 20+1).parallel().distinct().limit(5).sum();
# VM version: JDK 9-ea, VM 9-ea+130Benchmark Mode Cnt Score Error UnitsrndSum avgt 30 0.318 ± 0.003 us/oprndSumPar avgt 30 7.793 ± 0.026 us/op
JDK-8154387 Parallel unordered Stream.limit() tries to collect 128 elements even if limit is less
![Page 44: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/44.jpg)
44
parallel().skip()IntStream.range(0, 100_000_000) 104.5±4.4 ms .skip(99_000_000) .sum();
IntStream.range(0, 100_000_000) ? .parallel() .skip(99_000_000) .sum();
![Page 45: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/45.jpg)
45
![Page 46: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/46.jpg)
46
parallel().skip()API Note:While skip() is generally a cheap operation on sequential stream pipelines, it can be quite expensive on ordered parallel pipelines, especially for large values of n, since skip(n) is constrained to skip not just any n elements, but the first n elements in the encounter order.
![Page 47: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/47.jpg)
47
parallel().skip()IntStream.range(0, 100_000_000) 104.5±4.4 ms .skip(99_000_000) .sum();
IntStream.range(0, 100_000_000) 1.4±0.2 ms .parallel() (74.6×) .skip(99_000_000) .sum();
![Page 48: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/48.jpg)
48
parallel(): trySplit() (SIZED+SUBSIZED)
0..99_999_999
0..49_999_999 50_000_000..99_999_999
75_000_000..99_999_999
50_000_000..74_999_999
…………
25_000_000..49_999_999
……
0..24_999_999
……
![Page 49: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/49.jpg)
49
parallel().skip()(SIZED+SUBSIZED)
0..99_999_999
0..49_999_999 50_000_000..99_999_999
75_000_000..99_999_99950_000_000..74_999_999
……
![Page 50: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/50.jpg)
50
class Node { private String name; private List<Node> children;
public Node(String name, Node... children) { this.name = name; this.children = Arrays.asList(children); }
@Override public String toString() { return name; }
public Stream<Node> allNodes() { return …? }}
![Page 51: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/51.jpg)
51
class Node { private String name; private List<Node> children;
...
@Override public String toString() { return name; }
public Stream<Node> allNodes() { return children.isEmpty() ? Stream.of(this) : Stream.concat( Stream.of(this), children.stream().flatMap(Node::allNodes)); }}
![Page 52: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/52.jpg)
52
flatMap()Stream<Integer> a = ...;Stream<Integer> b = ...;Stream<Integer> c = ...;Stream<Integer> d = ...;Stream<Integer> res = Stream.concat( Stream.concat(Stream.concat(a, b), c), d);
Stream<Integer> res = Stream.of(a, b, c, d) .flatMap(Function.identity());
![Page 53: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/53.jpg)
53
flatMap() – декартово произведениеList<List<String>> input = asList(asList("a", "b", "c"), asList("x", "y"), asList("1", "2", "3"));
Supplier<Stream<String>> s = input.stream() .<Supplier<Stream<String>>>map(list -> list::stream) .reduce((sup1, sup2) -> () -> sup1.get() .flatMap(e1 -> sup2.get().map(e2 -> e1+e2))) .orElse(() -> Stream.of(""));
s.get().forEach(System.out::println);>> ax1>> ax2>> …>> cy3
![Page 54: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/54.jpg)
54
flatMap() parallel?Stream.of(list1, list2).parallel() .flatMap(List::stream).forEach(item -> {...});
list1
Item1Item2Item3
…Item1000
list2
Item1Item2Item3
…Item1000
![Page 55: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/55.jpg)
55
flatMap() parallel?Stream.of(list1, list2).parallel() .flatMap(l -> l.stream().parallel()).forEach(item -> {...});
list1
Item1Item2Item3
…Item1000
list2
Item1Item2Item3
…Item1000
![Page 56: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/56.jpg)
56
concat()-то лучше!Stream.concat(list1.stream().parallel(), list2.stream().parallel()).forEach(item -> {});
list1
Item1Item2
…Item500
Item501Item502
…Item1000
list2
Item1Item2
…Item500
Item501Item502
…Item1000
![Page 57: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/57.jpg)
57
flatMap() и short-circuitingprivate IntStream stream() {
if (!flatMap) {
return IntStream.rangeClosed(0, 1_000_000_000);
} else {
return IntStream.of(1_000_000_000)
.flatMap(x -> IntStream.rangeClosed(0, x));
}
}
![Page 58: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/58.jpg)
58
flatMap() и short-circuiting@Benchmarkpublic boolean hasGreaterThan2() { return stream().anyMatch(x -> x > 2);}
![Page 59: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/59.jpg)
59
flatMap() и short-circuiting@Benchmarkpublic boolean hasGreaterThan2() { return stream().anyMatch(x -> x > 2);}
# VM version: JDK 1.8.0_101, VM 25.101-b13Benchmark (flatMap) Mode Score Error UnitshasGreaterThan2 false avgt 0.040 ± 0.001 μs/ophasGreaterThan2 true avgt 980489.972 ± 12335.916 μs/op
![Page 60: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/60.jpg)
60
flatMap() и tryAdvance()flatMap = false;Spliterator<Integer> spliterator = stream().spliterator();spliterator.tryAdvance(System.out::println);>> 0
![Page 61: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/61.jpg)
61
flatMap() и tryAdvance()flatMap = true;Spliterator<Integer> spliterator = stream().spliterator();spliterator.tryAdvance(System.out::println);
![Page 62: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/62.jpg)
62
java.lang.OutOfMemoryError: Java heap space at java.util.stream.SpinedBuffer.ensureCapacity at java.util.stream.SpinedBuffer.increaseCapacity at java.util.stream.SpinedBuffer.accept at java.util.stream.IntPipeline$4$1.accept at java.util.stream.IntPipeline$7$1.lambda$accept$198 at java.util.stream.IntPipeline$7$1$$Lambda$7/1831932724.accept at java.util.stream.Streams$RangeIntSpliterator.forEachRemaining at java.util.stream.IntPipeline$Head.forEach at java.util.stream.IntPipeline$7$1.accept at java.util.stream.Streams$IntStreamBuilderImpl.tryAdvance at java.util.Spliterator$OfInt.tryAdvance ... at java.util.stream.StreamSpliterators$WrappingSpliterator.tryAdvance at by.jetconf.streamsamples.FlatMapTryAdvance.main
![Page 63: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/63.jpg)
63
flatMap() и tryAdvance()flatMap = true;Spliterator<Integer> spliterator = stream().spliterator();spliterator.tryAdvance(System.out::println);
![Page 64: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/64.jpg)
64
flatMap() и concat()flatMap = true;
stream().sum();
stream().findFirst(); // non-short-circuit
IntStream.concat(stream(), IntStream.of(1)).sum();
IntStream.concat(stream(), IntStream.of(1)).findFirst();
![Page 65: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/65.jpg)
65
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.stream.SpinedBuffer$OfInt.newArray at java.util.stream.SpinedBuffer$OfInt.newArray at java.util.stream.SpinedBuffer$OfPrimitive.ensureCapacity at java.util.stream.SpinedBuffer$OfPrimitive.increaseCapacity at java.util.stream.SpinedBuffer$OfPrimitive.preAccept at java.util.stream.SpinedBuffer$OfInt.accept ... at java.util.stream.Streams$ConcatSpliterator$OfInt.tryAdvance at java.util.stream.IntPipeline.forEachWithCancel at java.util.stream.AbstractPipeline.copyIntoWithCancel at java.util.stream.AbstractPipeline.copyInto at java.util.stream.AbstractPipeline.wrapAndCopyInto at java.util.stream.FindOps$FindOp.evaluateSequential at java.util.stream.AbstractPipeline.evaluate at java.util.stream.IntPipeline.findFirst at by.jetconf.streamsamples.ConcatFlat.main
![Page 66: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/66.jpg)
66
class Node { private String name; private List<Node> children;
...
@Override public String toString() { return name; }
public Stream<Node> allNodes() { return children.isEmpty() ? Stream.of(this) : Stream.concat( Stream.of(this), children.stream().flatMap(Node::allNodes)); }}
![Page 67: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/67.jpg)
67
Root
Child
n0 n1 n2 n3 n999999…
![Page 68: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/68.jpg)
68
root.allNodes().count()
root.allNodes().anyMatch(n -> false)
![Page 69: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/69.jpg)
69
count 29.4 ± 2.0 ms 80 001 KB/op
anyMatch 70.0 ± 6.0 ms 84 196 KB/op
![Page 70: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/70.jpg)
70
// with concatpublic Stream<Node> allNodes() { return children.isEmpty() ? Stream.of(this) : Stream.concat( Stream.of(this), children.stream().flatMap(Node::allNodes));}
// without concatpublic Stream<Node> allNodes() { return children.isEmpty() ? Stream.of(this) : Stream.of(Stream.of(this), children.stream().flatMap(Node::allNodes)) .flatMap(Function.identity());}
![Page 71: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/71.jpg)
71
count (concat) 29.4 ± 2.0 ms 80 001 KB/op (flatMap) 32.6 ± 2.0 ms 80 001 KB/op
anyMatch (concat) 70.0 ± 6.0 ms 84 196 KB/op (flatMap) 31.0 ± 2.3 ms 80 001 KB/op
![Page 72: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/72.jpg)
72
// with concatpublic Stream<Node> allNodes() { return children.isEmpty() ? Stream.of(this) : Stream.concat( Stream.of(this), children.stream().flatMap(Node::allNodes));}
// without concatpublic Stream<Node> allNodes() { return children.isEmpty() ? Stream.of(this) : Stream.of(Stream.of(this), children.stream().flatMap(Node::allNodes)) .flatMap(Function.identity());}
![Page 73: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/73.jpg)
73
import one.util.streamex.StreamEx;
public Stream<Node> allNodes() { return StreamEx.ofTree(this, n -> n.children.isEmpty() ? null : StreamEx.of(n.children));}
![Page 74: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/74.jpg)
74
count (concat) 29.4 ± 2.0 ms 80 001 KB/op (flatMap) 32.6 ± 2.0 ms 80 001 KB/op (StreamEx) 12.4 ± 0.2 ms 0.5 KB/op
anyMatch (concat) 70.0 ± 6.0 ms 84 196 KB/op (flatMap) 31.0 ± 2.3 ms 80 001 KB/op (StreamEx) 19.3 ± 0.3 ms 0.5 KB/op
![Page 75: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/75.jpg)
Stream и Iterator
![Page 76: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/76.jpg)
76
iterator()
Верните цикл for()!
![Page 77: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/77.jpg)
77
for vs forEach()for forEach()
Появился Java 1.5 Java 1.8
Нормальная отладка
Короткие стектрейсы
Checked exceptions
Изменяемые переменные
Досрочный выход по break
Параллелизм (всё равно не нужен)
![Page 78: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/78.jpg)
78
iterator()
![Page 79: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/79.jpg)
79
iterator()Stream<String> s = Stream.of("a", "b", "c");for(String str : (Iterable<String>)s::iterator) { System.out.println(str);}
![Page 80: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/80.jpg)
80
iterator()Stream<String> s = Stream.of("a", "b", "c");for(String str : (Iterable<String>)s::iterator) { System.out.println(str);}
// Joshua Bloch approvesfor(String str : StreamEx.of("a", "b", "c")) { System.out.println(str);}
![Page 81: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/81.jpg)
81
iterator()
IntStream s = IntStream.of(1_000_000_000) .flatMap(x -> IntStream.range(0, x));for(int i : (Iterable<Integer>)s::iterator) { System.out.println(i);}
![Page 82: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/82.jpg)
82
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at j.u.s.SpinedBuffer$OfInt.newArray at j.u.s.SpinedBuffer$OfInt.newArray at j.u.s.SpinedBuffer$OfPrimitive.ensureCapacity at j.u.s.SpinedBuffer$OfPrimitive.increaseCapacity at j.u.s.SpinedBuffer$OfPrimitive.preAccept at j.u.s.SpinedBuffer$OfInt.accept at j.u.s.IntPipeline$7$1.lambda$accept$198 ... at j.u.s.StreamSpliterators$AbstractWrappingSpliterator.fillBuffer at j.u.s.StreamSpliterators$AbstractWrappingSpliterator.doAdvance at j.u.s.StreamSpliterators$IntWrappingSpliterator.tryAdvance at j.u.Spliterators$2Adapter.hasNext at by.jetconf.streamsamples.IterableWorkaround.main
![Page 83: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/83.jpg)
83
Map<String, String> userPasswords = Files.lines(Paths.get("/etc/passwd")) .map(str -> str.split(":")) .collect(toMap(arr -> arr[0], arr -> arr[1]));
![Page 84: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/84.jpg)
84
Map<String, String> userPasswords = Files.lines(Paths.get("/etc/passwd")) .map(str -> str.split(":")) .collect(toMap(arr -> arr[0], arr -> arr[1]));
such stream
WOWmuch fluent
![Page 85: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/85.jpg)
85
Map<String, String> userPasswords;try (Stream<String> stream = Files.lines(Paths.get("/etc/passwd"))) { userPasswords = stream.map(str -> str.split(":")) .collect(toMap(arr -> arr[0], arr -> arr[1]));}
![Page 86: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/86.jpg)
86
Map<String, String> userPasswords;try (Stream<String> stream = Files.lines(Paths.get("/etc/passwd"))) { userPasswords = stream.map(str -> str.split(":")) .collect(toMap(arr -> arr[0], arr -> arr[1]));}
![Page 88: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/88.jpg)
88
Терминальные операции
Нормальные (с внутренним обходом):
forEach()collect()reduce()
findFirst()count()toArray()
…
![Page 89: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/89.jpg)
89
Терминальные операции
Нормальные (с внутренним обходом):
forEach()collect()reduce()
findFirst()count()toArray()
…
Причудливые(с внешним обходом):
iterator()spliterator()
![Page 90: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/90.jpg)
90
Use flatMapto save the Stream!
![Page 91: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/91.jpg)
91
flatMap<R> Stream<R> flatMap( Function<? super T,? extends Stream<? extends R>> mapper)
Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have been placed into this stream. (If a mapped stream is null an empty stream is used, instead.)
![Page 92: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/92.jpg)
92
Map<String, String> userPasswords = Stream.of(Files.lines(Paths.get("/etc/passwd"))) .flatMap(Function.identity()) .map(str -> str.split(":")) .collect(toMap(arr -> arr[0], arr -> arr[1]));
![Page 93: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/93.jpg)
93
Files.lines(Paths.get("/etc/passwd")) .spliterator().tryAdvance(...);// вычитываем одну строку, файл не закрываем
Stream.of(Files.lines(Paths.get("/etc/passwd"))) .flatMap(s -> s) .spliterator().tryAdvance(...);// вычитываем весь файл в память, файл закрываем
![Page 94: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/94.jpg)
94
Files.lines(Paths.get("/etc/passwd")) .spliterator().tryAdvance(...);// вычитываем одну строку, файл не закрываем
Stream.of(Files.lines(Paths.get("/etc/passwd"))) .flatMap(s -> s) .spliterator().tryAdvance(...);// вычитываем весь файл в память, файл закрываем
http://stackoverflow.com/a/32767282/4856258 (небуферизующий flatMap)
![Page 95: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/95.jpg)
95
There’s no way to save the Stream
![Page 96: Weird Stream API](https://reader036.vdocuments.site/reader036/viewer/2022062310/5877df081a28abaa6c8b6f27/html5/thumbnails/96.jpg)
96
Спасибо за внимание
https://twitter.com/tagir_valeev
https://github.com/amaembo
https://habrahabr.ru/users/lany