You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中用Stream获取两个Person列表中男性的对称差集?

问题描述

我定义了如下Java类:

public class Person {
    private String name;
    private String gender;
}

我拥有两个Person列表:
列表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"

我希望生成一个新列表,包含所有仅存在于其中一个列表中的男性,即既包含列表A中有但列表B中没有的男性,也包含列表B中有但列表A中没有的男性。我尝试用Stream实现,但尚未找到方法。


解决方案

要实现这个需求,我们可以通过Java Stream分步骤处理:

步骤说明

  1. 过滤男性数据:先从两个列表中筛选出男性,减少后续处理的无效数据。
  2. 提取姓名集合:将两个列表中男性的姓名存入Set,利用Set的快速查询特性判断存在性(假设姓名是Person的唯一标识)。
  3. 计算对称差集:分别找出仅在A中存在的男性、仅在B中存在的男性,最后合并两部分结果。

完整代码实现

首先给Person类补充必要的getter、构造方法以及equals/hashCode(保证集合操作的正确性):

import java.util.Objects;

public class Person {
    private String name;
    private String gender;

    public Person(String name, String gender) {
        this.name = name;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public String getGender() {
        return gender;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return Objects.equals(name, person.name) && Objects.equals(gender, person.gender);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, gender);
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', gender='" + gender + "'}";
    }
}

然后是核心逻辑代码:

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        // 初始化列表A
        List<Person> listA = List.of(
                new Person("Mike", "male"),
                new Person("Jane", "female"),
                new Person("Ellen", "female"),
                new Person("Ben", "male"),
                new Person("Jimmy", "male"),
                new Person("Maria", "female")
        );

        // 初始化列表B
        List<Person> listB = List.of(
                new Person("Ben", "male"),
                new Person("Maria", "female"),
                new Person("Jane", "female"),
                new Person("Brian", "male"),
                new Person("Sofia", "female"),
                new Person("John", "male"),
                new Person("Jimmy", "male")
        );

        // 提取列表A的男性姓名集合
        Set<String> maleNamesA = listA.stream()
                .filter(p -> "male".equals(p.getGender()))
                .map(Person::getName)
                .collect(Collectors.toSet());

        // 提取列表B的男性姓名集合
        Set<String> maleNamesB = listB.stream()
                .filter(p -> "male".equals(p.getGender()))
                .map(Person::getName)
                .collect(Collectors.toSet());

        // 获取仅在A中存在的男性
        List<Person> onlyInA = listA.stream()
                .filter(p -> "male".equals(p.getGender()))
                .filter(p -> !maleNamesB.contains(p.getName()))
                .collect(Collectors.toList());

        // 获取仅在B中存在的男性
        List<Person> onlyInB = listB.stream()
                .filter(p -> "male".equals(p.getGender()))
                .filter(p -> !maleNamesA.contains(p.getName()))
                .collect(Collectors.toList());

        // 合并结果
        List<Person> result = Stream.concat(onlyInA.stream(), onlyInB.stream())
                .collect(Collectors.toList());

        // 输出结果
        result.forEach(System.out::println);
    }
}

运行结果

执行后会输出:

Person{name='Mike', gender='male'}
Person{name='Brian', gender='male'}
Person{name='John', gender='male'}

内容的提问来源于stack exchange,提问作者TheStranger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 09:10:35