如何将List<Person>转换为Map<String,List<Double>>而不是Map<String,List<Person>>?

4
考虑到Person类有三个字段:name(String),age(int),salary(double)。
如果键名不唯一,则使用LinkedList来保存所有重复键的值,我想创建一个以name为键,以salary为值的映射(而不是Person对象本身),如果键名不唯一,则使用LinkedList来保存所有重复键的值。
我参考了下面链接中给出的解决方案:Idiomatically creating a multi-value Map from a Stream in Java 8但仍然不清楚如何创建值为Salary的HashMap。
我可以使用forEach()方法创建map<String, List<Double>>,代码如下:
List<Person> persons= new ArrayList<>();
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        persons.add(p4);

        Map<String, List<Double>> personsByName = new HashMap<>();

        persons.forEach(person ->
            personsByName.computeIfAbsent(person.getName(), key -> new LinkedList<>())
                    .add(person.getSalary())
        );

但我正在尝试使用“groupingBy&collect”创建地图。 如果我们想要将 Person 对象本身作为值,则给出以下代码:

Map<String, List<Person>> personsByNameGroupingBy = persons.stream()
                .collect(Collectors.groupingBy(Person::getName, Collectors.toList()));

但我想创建一个以薪资为值的地图,就像下面所示:

Map<String, List<Double>> 

如何实现这种情况?
2个回答

8
您可以使用Collectors.mappingPerson实例映射到相应的薪资:
Map<String, List<Double>> salariesByNameGroupingBy = 
    persons.stream()
           .collect(Collectors.groupingBy(Person::getName, 
                                          Collectors.mapping(Person::getSalary,
                                                             Collectors.toList())));

1
创建一个Map,然后使用forEach方法,对于每个项目,检查你的Map是否有特定的键,如果没有,则添加新的键和空列表来收集数据。请参考下面的代码。
Map<String, List<Double>> data = new HashMap<>();

persons.forEach(
    p->{
       String key = p.getName();
       if(!data.contains(key)){
           data.put(key, new ArrayList());
       }
       data.get(key).add(p.getSalary);
    }
);

它可以工作,但如果您正在使用类似于票证描述中提到的forEach,则也可以使用computeIfAbsent。好的解决方案,顺便说一句.. :) - Nipun
感谢您,因为现在我也实现了所选的答案。哈哈 - Febrinanda Endriz Pratama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接