更新时间:2022-04-18 07:09:29
使用流,您可以使用 Collectors.groupingBy
以及 Collectors.mapping
:
With streams, you could use Collectors.groupingBy
along with Collectors.mapping
:
Map<String, Set<String>> map = list.stream()
.collect(Collectors.groupingBy(
Student::getName,
Collectors.mapping(student -> getNum(student.getAddr()),
Collectors.toSet())));
我选择创建集合而不是列表地图,因为它似乎你不希望列表中有重复项。
I've chosen to create a map of sets instead of a map of lists, as it seems that you don't want duplicates in the lists.
如果你确实需要列表而不是集合,那么首先更有效率收集到集合,然后将集合转换为列表:
If you do need lists instead of sets, it's more efficient to first collect to sets and then convert the sets to lists:
Map<String, List<String>> map = list.stream()
.collect(Collectors.groupingBy(
Student::getName,
Collectors.mapping(s -> getNum(s.getAddr()),
Collectors.collectingAndThen(Collectors.toSet(), ArrayList::new))));
这使用 Collectors.collectingAndThen
,首先收集然后转换结果。
This uses Collectors.collectingAndThen
, which first collects and then transforms the result.
另一种更紧凑的方式,没有流:
Another more compact way, without streams:
Map<String, Set<String>> map = new HashMap<>(); // or LinkedHashMap
list.forEach(s ->
map.computeIfAbsent(s.getName(), k -> new HashSet<>()) // or LinkedHashSet
.add(getNum(s.getAddr())));
此变体使用 Iterable.forEach
迭代列表和 Map.computeIfAbsent
按学生名称对转换后的地址进行分组。
This variant uses Iterable.forEach
to iterate the list and Map.computeIfAbsent
to group transformed addresses by student name.