需求
有这么一个需求,学校举办了一场运动会,要求获取同时参加了田径和跳远项目的学生名单。
技术实现
为了更直观描述技术实现,先看看项目代码初始代码:
代表学生对象的实体类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<Student> raceStudents = new ArrayList<>();
raceStudents.add(s1);
raceStudents.add(s2);
raceStudents.add(s3);
raceStudents.add(s6);
raceStudents.add(s9);
//运动会名单
List<Student> 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
的集合原始数据只会保留重叠的列表,如果还需要使用原始数据,可以拷贝一个新的列表进行取重。