Java 8 java 8中的parallelStream()能保证顺序吗?

Java 8 java 8中的parallelStream()能保证顺序吗?,java-8,java-stream,Java 8,Java Stream,我试图理解java 8中parallelStream()的行为。这是我的示例代码 List<Person> javaProgrammers = new ArrayList<Person>() { { add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 43, 2000)); add(new Person("Tamsen", "Brittany", "Java p

我试图理解java 8中
parallelStream()
的行为。这是我的示例代码

List<Person> javaProgrammers = new ArrayList<Person>() {
    {
        add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 43, 2000));
        add(new Person("Tamsen", "Brittany", "Java programmer", "female", 33, 1500));
        add(new Person("Floyd", "Donny", "Java programmer", "male", 33, 1800));
        add(new Person("Sindy", "Jonie", "Java programmer", "female", 32, 1600));
        add(new Person("Vere", "Hervey", "Java programmer", "male", 22, 1200));
        add(new Person("Maude", "Jaimie", "Java programmer", "female", 33, 1900));
        add(new Person("Shawn", "Randall", "Java programmer", "male", 33, 2300));
        add(new Person("Jayden", "Corrina", "Java programmer", "female", 33, 1700));
        add(new Person("Palmer", "Dene", "Java programmer", "male", 33, 2000));
        add(new Person("Addison", "Pam", "Java programmer", "female", 34, 1300));
    }
};

System.out.println("Serial:" + javaProgrammers.stream().filter(person -> person.age == 33).findFirst().toString());
System.out.println("Parallel:" + javaProgrammers.parallelStream().filter(person -> person.age == 33).findFirst().toString());
List javaProgrammers=new ArrayList(){
{
添加(新人(“Elsdon”、“Jaycob”、“Java程序员”、“男性”,432000年));
添加(新人(“Tamsen”、“Brittany”、“Java程序员”、“女性”,331500));
添加(新人(“弗洛伊德”、“唐尼”、“Java程序员”、“男性”,331800));
添加(新人(“Sindy”、“Jonie”、“Java程序员”、“女性”,321600));
添加(新人(“Vere”、“Hervey”、“Java程序员”、“男性”,221200));
添加(新人(“Maude”、“Jaimie”、“Java程序员”、“女性”,33,1900));
添加(新人(“Shawn”、“Randall”、“Java程序员”、“男性”,332300));
添加(新人物(“Jayden”、“Corrina”、“Java程序员”、“女性”,331700));
添加(新人(“帕尔默”、“丹恩”、“Java程序员”、“男性”,33,2000年));
添加(新人(“Addison”、“Pam”、“Java程序员”、“女性”,341300));
}
};
System.out.println(“Serial:+javaProgrammers.stream().filter(person->person.age==33.findFirst().toString());
System.out.println(“Parallel:+javaProgrammers.parallelStream().filter(person->person.age==33.findFirst().toString());
这里我比较了
stream()
parallelStream()
,我希望
Brittany Tamsen
总是在
stream()
调用中返回,因为这是第一个匹配。但是对于
parallelStream()
我不希望
Brittany Tamsen
总是返回,因为它可以是任何匹配项之一,因为我希望它并行运行

但问题是它也总是返回
Brittany Tamsen
。所以它看起来不像是并行运行的


我是不是遗漏了什么

除了Bohemian的答案之外,重要的是要补充一点,是的,
findFirst()
将返回与谓词匹配的第一个元素,无论流是否平行,因为在这种情况下流具有遭遇顺序(从列表创建)


相反,
findAny()
可以自由返回与谓词匹配的任何元素(因此,如果您不真正关心返回哪个匹配元素,则应该优先考虑,因为在并行流的情况下,它可能允许更快地返回).

中有一整段是关于排序的,另一段是关于并发和排序之间的交互

摘录(强烈建议阅读其余部分):

流可能有也可能没有定义的遭遇顺序。是否 流的遭遇顺序取决于源和目标 中间业务。某些流源(如列表或 数组)本质上是有序的

然后,文档本身引用了上面定义的遭遇顺序概念

返回描述此流的第一个元素的可选值,或 如果流为空,则为空可选。如果溪流没有遭遇 顺序,则可以返回任何元素


和文档还描述了一些与排序相关的行为,以便更复杂地使用并行流。

请注意,不鼓励使用双括号初始化模式,因为它会创建额外的类。不过,我的IDE(idea)没有抱怨。推荐的方法是什么?你说的附加类是什么意思?这是一个糟糕的启发。仅仅因为你的IDE没有抱怨它并不意味着它是高效的。毕竟,它并不比你聪明。它甚至不比直截了当的解决方案短,例如,如果你不需要可调整大小的列表,请使用
list javaProgrammers=Arrays.asList(new Person(…)、new Person(…)、…),它更短更高效。如果您确实需要一个可调整大小的
ArrayList
,您可以将该列表传递给
ArrayList
的构造函数,或者构造一个初始为空的
ArrayList
并使用
集合,但它仍然比双花括号子类化(以及潜在的内存泄漏创建)要好。关于实际问题,可能会有所帮助。