【问题标题】:How to convert List<Person> to Map<String, List<Double>> instead of Map<String, List<Person>>?如何将 List<Person> 转换为 Map<String, List<Double>> 而不是 Map<String, List<Person>>?
【发布时间】:2019-01-23 08:20:59
【问题描述】:

考虑Person类有name(String)、age(int)、salary(double)三个字段。

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

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

我可以使用 forEach() 创建map&lt;String, List&lt;Double&gt;&gt;。代码如下:

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>> 

如何实现这个场景?

【问题讨论】:

    标签: java java-8 java-stream multimap


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      创建一个 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,就像票证描述本身中提到的那样。好的解决方案顺便说一句.. :)
      • 感谢您,因为现在我也实施了选定的答案。哈哈
      猜你喜欢
      • 2023-04-08
      • 2015-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-28
      • 2020-04-01
      • 1970-01-01
      相关资源
      最近更新 更多