当前位置: 代码迷 >> 综合 >> Java:数据集合List与Map的性能比较案例
  详细解决方案

Java:数据集合List与Map的性能比较案例

热度:72   发布时间:2024-02-24 01:09:16.0

假设有这样的一个场景:一组学生数据,一组老师的数据,属性分别如下

public class Student {private String courseId;private String sduName;public Student(String courseId, String sduName) {super();this.courseId = courseId;this.sduName = sduName;}public String getCourseId() {return courseId;}public void setCourseId(String courseId) {this.courseId = courseId;}public String getSduName() {return sduName;}public void setSduName(String sduName) {this.sduName = sduName;}}
public class Teacher {private String courseId;private String teaName;public Teacher(String courseId, String teaName) {super();this.courseId = courseId;this.teaName = teaName;}public String getCourseId() {return courseId;}public void setCourseId(String courseId) {this.courseId = courseId;}public String getTeaName() {return teaName;}public void setTeaName(String teaName) {this.teaName = teaName;}	}

现在需要找到学生与老师的courseId相等的数据,再进行一些代码操作(这里不考虑将数据存入数据库进行表关联查询)。

很容易想到的一个代码写法如下:

List<Student> listStudent = getStuList(); // 封装的getStuList()方法不做展示
List<Teacher> listTeacher = getTeacherList(); // 封装的getTeacherList()方法不做展示listStudent.forEach(stu -> {listTeacher.forEach(tea -> {// 找到courseId相等的student和teacherif(stu.getCourseId().equals(tea.getCourseId())){// do something}});
});

就是分别用两个List载入学生和老师的数据,两层List遍历就可以得到。

这样的写法当然没有问题,但是,如果两个List的数据量都十分庞大呢?比如有几万条数据,这样遍历的效率就不敢想象了。

有没有更好的写法呢?有,用Map:

Map<String, Student> listStudent = getStuList(); // 封装的getStuList()方法不做展示
Map<String, Teacher> listTeacher = getTeacherList(); // 封装的getTeacherList()方法不做展示// 获取所有的courseId
Set<String> set = listStudent.keySet();set.forEach(courseId -> {if(listTeacher.get(courseId) != null){// do something}
});

这里说明一下:Map的 key 为需要映射的属性,即 courseId

这样的话,只需要对其中一个Map进行遍历就行了,然后通过 Map.get(key)的方法去找另一个 Map中是否有对应数据。

Map.get(key) 用的是 Hash 算法寻找的,而前面的代码用的List来存数据,需要将 List 迭代一遍才能找到对应的数据,两种策略的效率在数据量很小的情况下看不出明显的差异,数据量越大,这个效率上的差异越明显。很显然,后一种写法是更合适的。

这里需要说明一点:

如果要考虑线程安全的情况下,可将 HashMap 替换成  ConcurrentHashMap

ConcurrentHashMap <String, Student> listStudent = getStuList(); // 封装的getStuList()方法不做展示
ConcurrentHashMap <String, Teacher> listTeacher = getTeacherList(); // 封装的getTeacherList()方法不做展示// 获取所有的courseId
Set<String> set = listStudent.keySet();
set.forEach(courseId -> {if(listTeacher.get(courseId) != null){// do something}
});