Вы используете TreeSet, который упорядочивает элементы. Итак, элементами будут:
-4, -3, 1, 3, 10
Использование последовательного потока не меняет порядок, поэтому результат не зависит от свойства потока быть упорядоченным/неупорядоченным, как вы можете видеть в первом примере "Последовательный поток" (и как вы сами заметили).
l.stream().map(s->s+" ").forEach(System.out::print);
Результат: -4 -3 1 3 10
l.stream().unordered().map(s->s+" ").forEach(System.out::print);
Результат: -4 -3 1 3 10
Если вы сделаете поток параллельным, то может быть создано более одного потока, и результат больше не гарантируется, поскольку он зависит от конкретного выполнения. Также обратите внимание, что forEach() не является упорядоченной операцией, что означает, что она выполняется всякий раз, когда в ее конвейере есть что-то для обработки. См. пример «Неупорядоченные операции над параллельным потоком»:
l.stream().parallel().map(s->s+" ").forEach(System.out::print);
Результат: 3 10 -3 1 -4
l.stream().unordered().map(s->s+" ").parallel().forEach(System.out::print);
Результат: 3 -4 -3 1 10
Все меняется, когда вы используете упорядоченные операции (такие как findFirst(), limit() и skip()) в параллельном потоке. Когда вы используете findFirst() в конвейере, вы действительно хотите иметь первый элемент, в соответствии с порядком элементов в потоке, вам просто не нужен какой-либо элемент, и в этом случае вы будете использовать findAny(). Чтобы получить детерминированные результаты этих операций, вы теряете преимущества использования параллельного потока, потому что выполнение должно быть сериализовано для обработки элементов в определенном порядке.
l.stream().parallel().skip(2).limit(2).findFirst().ifPresent(System.out::print);
Результат: 1 . Этот результат всегда будет одинаковым, независимо от того, сколько раз вы выполняете код.
l.stream().unordered().parallel().skip(2).limit(2).findFirst().ifPresent(System.out::print);
Результат: -3 . Этот результат может (а может и не меняться) каждый раз при выполнении кода, потому что мы указали, что порядок не важен.
Вот полный код:
public static void main(String[] args) {
Set<Integer> l = new TreeSet<>();
l.add(1);
l.add(10);
l.add(3);
l.add(-3);
l.add(-4);
System.out.println("Serial Stream");
l.stream().map(s->s+" ").forEach(System.out::print);
System.out.println();
l.stream().unordered().map(s->s+" ").forEach(System.out::print);
System.out.println("\n");
System.out.println("Unordered Operations on a Parallel Stream");
l.stream().parallel().map(s->s+" ").forEach(System.out::print);
System.out.println();
l.stream().unordered().map(s->s+" ").parallel().forEach(System.out::print);
System.out.println("\n");
System.out.println("Ordered Operations on a Parallel Stream");
l.stream().parallel().skip(2).limit(2).findFirst().ifPresent(System.out::print);
System.out.println();
l.stream().unordered().parallel().skip(2).limit(2).findFirst().ifPresent(System.out::print);
System.out.println("\n");
}
Серийный поток
-4 -3 1 3 10
-4 -3 1 3 10
Неупорядоченные операции над параллельным потоком
3 10 -3 -4 1
-3 1 3 10 -4
Упорядоченные операции над параллельным потоком
1
-3
person
Luigi Rubino
schedule
26.06.2016