Java 8 - как только Stream используется и работает, выдавая ошибку, но в другом случае его нет - PullRequest
0 голосов
/ 07 октября 2018

Я новичок в Java 8 и хочу понять разницу между двумя сценариями.Я знаю, что если поток используется и используется, то поток не может быть использован повторно, и это приведет к ошибке.

Сценарий-1:

List<String> title = Arrays.asList("Java8", "In", "Action");
        Stream<String> s = title.stream();
        s.forEach(System.out::println);
        s.forEach(System.out::println); // THIS WILL GIVE ERROR - streams has been already operated and closed.

Когда я запустлюэто, я получаю ошибку ниже ... что справедливо.

Java8
In
Action
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
    at java.util.stream.AbstractPipeline.sourceStageSpliterator(Unknown Source)
    at java.util.stream.ReferencePipeline$Head.forEach(Unknown Source)
    at com.test.Java8InAction.CH4.TraversableOnlyOnce.main(TraversableOnlyOnce.java:12)

Сценарий-2:

// Filtering unique elements
List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream().forEach(System.out::println);
numbers.stream().filter(n -> n % 2 == 0).distinct().forEach(System.out::println);
numbers.stream().filter(n -> n % 2 == 0).forEach(System.out::println);

Здесь также я управлял потоком и закрывалоперация терминала, тогда почему я не получил никакой ошибки?

Ответы [ 4 ]

0 голосов
/ 08 октября 2018

forEach является терминальной операцией.

После выполнения терминальной операции потоковый конвейер считается использованным и больше не может использоваться;

https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

0 голосов
/ 07 октября 2018

Потому что поток может быть использован только один раз.Если вы хотите использовать несколько раз, используйте для этого Поставщик .

Supplier<Stream<String>> streamSupplier = ()-> Stream.of("Java8", "In", "Action");

, затем используйте get для создания нового потока.

streamSupplier.get().forEach(System.out::println);

но во втором сценарии вы каждый раз создаете новый поток.

0 голосов
/ 07 октября 2018

.stream() создает новый экземпляр Stream, несмотря на то, что он вызывается в той же коллекции

0 голосов
/ 07 октября 2018

Два вызова s.forEach используют один и тот же поток, следовательно, исключение в первом примере, тогда как вызов метода stream() -> numbers.stream() генерирует (выдает) новый поток каждый раз , следовательно, не выдает "java.lang.IllegalStateException: поток уже был обработан или закрыт" .

...