Java 8:从列表中高效地收集元素到TreeMap中

huangapple go评论76阅读模式
英文:

Java 8: Efficient way to Collect elements as TreeMap from List

问题

我有一个以下的Student对象

class Student{
	String name,email,country;
	//getters setters
}

我需要将元素收集为TreeMap<String,List<String>>,其中键是学生的country,值是email列表

Map<String, List<Student>> countryStudents = students.stream()
            .collect(Collectors.groupingBy(Student::getCountry));
Map<String,List<String>> map = new HashMap<>();
		countryStudents .entrySet().forEach(entry -> map.put(entry.getKey(),entry.getValue().stream().map(student -> student .getEmail()).collect(Collectors.toList())));

想知道是否有更高效的方法来完成这个任务,而不是分两次迭代。

英文:

I have a Student object as below

class Student{
	String name,email,country;
	//getters setters
}

And I need collect the elements as TreeMap<String,List<String>> where key is student's country and value is the list of email

Map<String, List<Student>> countryStudents = students.stream()
            .collect(Collectors.groupingBy(Student::getCountry));
Map<String,List<String>> map = new HashMap<>();
		countryStudents .entrySet().forEach(entry -> map.put(entry.getKey(),entry.getValue().stream().map(student -> student .getEmail()).collect(Collectors.toList())));

Am wondering if is there any efficient way to do this instead of doing it in 2 iterations.

答案1

得分: 3

你可以使用groupingBy收集器和mapping收集器一起进行操作,以在一次遍历中完成。以下是示例:

Map<String, List<String>> map = students.stream()
    .collect(Collectors.groupingBy(Student::getCountry, TreeMap::new, 
        Collectors.mapping(Student::getEmail, Collectors.toList())));

另外,一个更好的方法是使用computeIfAbsent在单次列表遍历中构建映射。如果我是你,我宁愿使用这种方法:

Map<String, List<String>> stdMap = new TreeMap<>();
for (Student student : students) 
    stdMap.computeIfAbsent(student.getCountry(), unused -> new ArrayList<>())
        .add(student.getEmail());
英文:

You can use groupingBy collector along with mapping collector to do it in one pass. Here's how it looks.

Map&lt;String, List&lt;String&gt;&gt; map = students.stream()
	.collect(Collectors.groupingBy(Student::getCountry, TreeMap::new, 
		Collectors.mapping(Student::getEmail, Collectors.toList())));

Alternatively, a much better approach is to use computeIfAbsent to construct the map in single pass over the list. If I were you, I would rather use this.

Map&lt;String, List&lt;String&gt;&gt; stdMap = new TreeMap&lt;&gt;();
for (Student student : students) 
	stdMap.computeIfAbsent(student.getCountry(), unused -&gt; new ArrayList&lt;&gt;())
		.add(student.getEmail());

huangapple
  • 本文由 发表于 2020年10月10日 11:19:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/64289632.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定