我有以下课程:
public class Person {
private String name;
private String gender;
}
然后我有两个人员名单
名单A:
index 0: name: "Mike", gender: "male"
index 1: name: "Jane", gender: "female"
index 2: name: "Ellen", gender: "female"
index 3: name: "Ben", gender: "male"
index 4: name: "Jimmy", gender: "male"
index 5: name: "Maria", gender: "female"
名单B:
index 0: name: "Ben", gender: "male"
index 1: name: "Maria", gender: "female"
index 2: name: "Jane", gender: "female"
index 3: name: "Brian", gender: "male"
index 4: name: "Sofia", gender: "female"
index 5: name: "John", gender: "male"
index 6: name: "Jimmy", gender: "male"
我想创建一个新列表,其中包含不在两个列表中的所有男性的姓名。
因此从示例来看,列表将如下所示:
index 0: name: "Mike", gender: "male"
index 1: name: "John", gender: "male"
index 2: name: "Brian", gender: "male"
这里棘手的事情是过滤是双向的。我希望最终列表包含列表 A 中但不在列表 B 中的男性,以及列表 B 中但不在列表 A 中的男性。我无法找到如何执行此操作,但我'我尝试使用流来完成它..
不是超级有效,但有效
List<Person> r =
Stream.concat(
a.stream().filter(e -> e.isMale() && !b.contains(e)),
b.stream().filter(e -> e.isMale() && !a.contains(e))
)
.collect(Collectors.toList());
更易读的版本,可存储部分结果
List<Person> aNotB = a.stream().filter(e -> e.isMale() && !b.contains(e)).collect(Collectors.toList());
List<Person> bNotA = b.stream().filter(e -> e.isMale() && !a.contains(e)).collect(Collectors.toList());
List<Person> r = new ArrayList<>(aNotB);
r.addAll(bNotA);
List<String> malesNotInBothLists = listA.stream()
.filter(p -> p.getGender().equals("male"))
.filter(p -> !listB.stream().anyMatch(b -> b.getName().equals(p.getName())))
.map(Person::getName)
.collect(Collectors.toList());
malesNotInBothLists.addAll(listB.stream()
.filter(p -> p.getGender().equals("male"))
.filter(p -> !listA.stream().anyMatch(a -> a.getName().equals(p.getName())))
.map(Person::getName)
.collect(Collectors.toList()));`enter code here`
Set<String> namesA = listA.stream()
.filter(p -> "male".equals(p.gender))
.map(p -> p.name)
.collect(Collectors.toUnmodifiableSet());
Set<String> namesB = listB.stream()
.filter(p -> "male".equals(p.gender))
.map(p -> p.name)
.collect(Collectors.toUnmodifiableSet());
List<String> result = Stream.concat(
namesA.stream().filter(Predicate.not(namesB::contains)),
namesB.stream().filter(Predicate.not(namesA::contains))
).toList();
这首先构建了
Set
和 listA
中男性名字的 listB
。事实上,这些是 Set
而不是 List
很重要,因为检查一个元素是否在 Set
中比在 List
中快得多(通常 Set
的时间为常数,但为线性时间)对于List
)。
然后,这将创建一个组合结果
List
,其中包含 namesA
中不在 namesB
中的所有元素,反之亦然。