如何将List <person>转换为Map <string,list <double =“” >>而不是Map <string,list <person =“” >>?

时间:2019-01-23 08:20:59

标签: java java-8 java-stream multimap

考虑Person类具有三个字段,名称(字符串),年龄(整数),薪水(双精度)。

我想创建一个名称为键,值为薪水的地图(而不是Person对象本身),如果键不是唯一的,则使用linkedList来保存所有重复键的值。

我指的是以下链接中给出的解决方案: Idiomatically creating a multi-value Map from a Stream in Java 8 ,但仍不清楚如何使用Salary作为值来创建哈希图

我可以使用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 个答案:

答案 0 :(得分:7)

您可以使用Collectors.mappingPerson实例映射到相应的薪金:

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

答案 1 :(得分:1)

创建一个地图,然后对每个项目执行每个,请检查您的地图是否具有特定的密钥,如果不,放入新的键和emptyList来收集您的数据。检查下面的代码。

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);
    }
);