Rav*_*avi 7 java java-8 java-stream
我有两个不同的相同对象列表,但不同的属性和这些对象中的公共标识符.我想迭代第一个列表并从第二个列表中获取相应的对象(具有公共属性),然后将这些对象包装起来,最后使用Java Streams将该对象添加到列表中.
这是我采取的例子.
private class Person {
private String name;
private boolean isSenior;
private Person(String name, boolean isSenior) {
this.name = name;
this.isSenior = isSenior;
}
public String getName() {
return name;
}
public boolean isSenior() {
return isSenior;
}
@Override
public String toString() {
return name + ": " + isSenior;
}
}
private class PersonWrapper {
private Person jrPerson;
private Person srPerson;
private PersonWrapper(Person jrPerson, Person srPerson) {
this.jrPerson = jrPerson;
this.srPerson = srPerson;
}
public Person getJrPerson() {
return jrPerson;
}
public Person getSrPerson() {
return srPerson;
}
@Override
public String toString() {
return jrPerson.toString() + "-" + srPerson.toString();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,在主类中,我将创建两个这样的列表实例
List<Person> jrPersons = new ArrayList<>();
List<Person> srPersons = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
并按以下方式添加对象
jrList.add(new Person("John", false));
jrList.add(new Person("Paul", false));
jrList.add(new Person("Mike", false));
seniorList.add(new Person("John", true));
seniorList.add(new Person("Paul", true));
seniorList.add(new Person("Mike", true));
Run Code Online (Sandbox Code Playgroud)
现在,我想迭代jrList并在srList(同名)中找到相应的Person对象.然后我将这些对象包装PersonWrapper为一个列表.
到目前为止,这就是我一直在做的事情
List<PersonWrapper> wrapperList = new ArrayList<>();
jrList.forEach(jr -> seniorList.stream().filter(sr -> jr.getName().equals(sr.getName())).map(sr -> new PersonWrapper(jr, sr)).collect(Collectors.toList()));
Run Code Online (Sandbox Code Playgroud)
现在,我想知道如何Collectors.toList()替换wrapperList输出或如何Collectors.toList()添加输出wrapperList.
请帮助我实现这一目标.
Lin*_*ica 12
而不是forEach从一开始就使用刚刚使用的流:
List<PersonWrapper> wrapperList = jrList.stream()
.flatMap(jr -> seniorList.stream()
.filter(sr -> jr.getName().equals(sr.getName()))
.map(sr -> new PersonWrapper(jr, sr))
)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
通过使用flatMap你可以扁平化流(流Stream<Stream<PersonWrapper>>)集成到一个流(Stream<PersonWrapper>)
如果你不能自己实例化wrapperList或者真的需要追加它.您可以将以上代码段更改为以下内容:
List<PersonWrapper> wrapperList = new ArrayList<>();
jrList.stream()
.flatMap(jr -> seniorList.stream()
.filter(sr -> jr.getName().equals(sr.getName()))
.map(sr -> new PersonWrapper(jr, sr))
)
.forEach(wrapperList::add);
Run Code Online (Sandbox Code Playgroud)
而利诺的回答当然是正确的。我认为,如果给定的 person 对象最多jrList只能有一个对应的匹配项seniorList,换句话说,如果它是 1-1 关系,那么您可以通过查找第一个匹配项来改进Lino给出的解决方案,如下所示:
List<PersonWrapper> resultSet = jrList.stream()
.map(p -> seniorList.stream()
.filter(sr -> p.getName().equals(sr.getName()))
.findFirst()
.map(q -> new PersonWrapper(p, q))
.get())
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
或者,如果不能保证 中的每个人jrList都会有相应的匹配项,seniorList则将上述查询更改为:
List<PersonWrapper> resultSet = jrList.stream()
.map(p -> seniorList.stream()
.filter(sr -> p.getName().equals(sr.getName()))
.findFirst()
.map(q -> new PersonWrapper(p, q))
.orElse(null))
.filter(Objects::nonNull)
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
不同之处在于,现在我们不再调用get()结果,而是findFirst()提供默认值,以防找不到相应的值,然后我们在后续的中间操作中取出不需要的值。orElsefindFirstfilternull