java:retainAll获取俩个自定义实体对象集合的重叠数据


需求

有这么一个需求,学校举办了一场运动会,要求获取同时参加了田径和跳远项目的学生名单。

技术实现

为了更直观描述技术实现,先看看项目代码初始代码:

代表学生对象的实体类Student(id为唯一标识码):

public class Student
{
    // 学生姓名
    private String name;
    // 学号
    private String id;

    //省略getter setter 构造器方法
}

学生数据,运动名单数据初始化:

        Student s1 = new Student("小红","1");
        Student s2 = new Student("小白","2");
        Student s3 = new Student("小四","3");
        Student s4 = new Student("小三","4");
        Student s5 = new Student("老王","5");
        Student s6 = new Student("老李","6");
        Student s7 = new Student("欣欣","7");
        Student s8 = new Student("向荣","8");
        Student s9 = new Student("it民工","9");

        //田径名单
        List raceStudents = new ArrayList<>();
        raceStudents.add(s1);
        raceStudents.add(s2);
        raceStudents.add(s3);
        raceStudents.add(s6);
        raceStudents.add(s9);

        //运动会名单
        List jumpStudents = new ArrayList<>();
        jumpStudents.add(s1);
        jumpStudents.add(s6);
        jumpStudents.add(s7);
        jumpStudents.add(s8);
        jumpStudents.add(s9);

通常,我们可以用一个中规中矩的方法来获取俩分名单的重合学生列表,先遍历田径列表,取该列表中的每一条学生对象跟运动会列表中的所有学生做比较,如果id相同,就把这个学生对象放入一个新的集合中,这样就可以获取到需求中所需要的同时参加俩项运动的学生数据(俩个列表中的重合数据)。

以上方法看似很方便的解决了问题,但是由于多层嵌套在数据量大的情况下将会严重影响执行效率。

下面介绍jdk自带的属于List的apiretainAll,该方法可以快速的从俩个集合中获取重叠的数据。对于java内置的基础数据类型,直接调用这个方法就可以,如果是自定义数据类型(如本文中的Student)就需要重写该实体类的equals(),原因是retainAll内部通过集合的contains方法,而该方法就是用equals()判断是否相等的(貌似jdk中判断对象是否相等都是用的这个方法)。

最后重写Student的equals方法:

    @Override
    public boolean equals(Object obj)
    {
        if (obj == null)
        {
            return false;
        }

        return name == null ? false : this.id.equals(((Student) obj).getId());
    }

获取重叠的数据:

 raceStudents.retainAll(jumpStudents);

需要注意的是,执行retainAll的集合原始数据只会保留重叠的列表,如果还需要使用原始数据,可以拷贝一个新的列表进行取重。

你可能感兴趣的:(java)