简体   繁体   English

你如何转换地图 <String, Person> 到地图 <String, Integer> 在java流里面收集?

[英]How do you convert Map<String, Person> to Map<String, Integer> in java streams inside collect?

Imagine you have a list of people, Roberts, Pauls, Richards, etc, these are people grouped by name into Map<String, List<Person>> . 想象一下,你有一个人名单,Roberts,Pauls,Richards等,这些是按名称分组到Map<String, List<Person>> You want to find the oldest Paul, Robert, etc... You can do it like so: 你想找到最老的保罗,罗伯特等......你可以这样做:

public static void main(String... args) {
        List<Person> people = Arrays.asList(
                new Person(23, "Paul"),
                new Person(24, "Robert"),
                new Person(32, "Paul"),
                new Person(10, "Robert"),
                new Person(4, "Richard"),
                new Person(60, "Richard"),
                new Person(9, "Robert"),
                new Person(26, "Robert")
        );

        Person dummy = new Person(0, "");
        var mapping = people.stream().collect(groupingBy(Person::getName, reducing(dummy, (p1, p2) -> p1.getAge() < p2.getAge() ? p2 : p1)));
        mapping.entrySet().forEach(System.out::println);
    }

Say, I want to get a mapping in the form of Map<String, Integer> instead of Map<String, Person> , I can do it like so: 说,我想以Map<String, Integer>的形式获取映射而不是Map<String, Person> ,我可以这样做:

var mapping = people.stream().collect(groupingBy(Person::getName, mapping(Person::getAge, reducing(0, (p1, p2) -> p1 < p2 ? p2 : p1))));

The steps above are: 以上步骤是:

  • Group by name into Map<String/*Name*/, List<Person>> 按名称分组到Map<String/*Name*/, List<Person>>
  • Map that List<Person> into List<Integer> List<Person>映射到List<Integer>
  • Find maximum Integer in those lists. 在这些列表中查找最大整数。

I was wondering how to do: 我想知道该怎么做:

  • Group by name into Map<String, List<Person>> 按名称分组到Map<String, List<Person>>
  • Find the oldest person in each group name, getting Map<String, Person> 找到每个组名中最老的人,获取Map<String, Person>
  • Convert Map<String, Person> into Map<String, Integer> . Map<String, Person>转换为Map<String, Integer> And I want to do all that inside that chain of groupingBy's, reducing's and mapping's. 我想在分组链中做所有这些,减少和映射。

This is the "pseudocode": 这是“伪代码”:

var mapping = people.stream().collect(groupingBy(Person::getName, reducing(dummy, (p1, p2) -> p1.getAge() < p2.getAge() ? p2 : p1 /*, have to write some other collector factory method here*/)));

How can I achieve this? 我怎样才能做到这一点?

It is more straightforward to do this with the 3-argument version of toMap collector : 使用toMap collector3参数版本更简单:

people.stream().collect(toMap(
        Person::getName, 
        Person::getAge, 
        Integer::max
    ));

If you really want to use groupingBy as mentioned in the problem statement, you can still do it like this: 如果你真的想使用问题陈述中提到的groupingBy ,你仍然可以这样做:

final Map<String, Integer> oldestPersonByName = people.stream()
        .collect(Collectors.groupingBy(Person::getName, Collectors.reducing(0, Person::getAge, Integer::max)));

For the reduction you have to pass an identity element, mapping function and a binary operator used to reduce, which is max in this case. 为了减少,你必须传递一个标识元素,映射函数和用于减少的二元运算符,在这种情况下是max

I think it would be like the following, also using maxBy instead of reducing . 我认为它会像下面这样,也使用maxBy而不是reducing

people.stream().collect(
    groupingBy(
        Person::getName,
        collectingAndThen(
            maxBy(Comparator.comparing(Person::getAge)),
            (Optional<Person> max) -> max.get().getAge()
        )
    )
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Java 8流,如何转换Map <String, Map<String, List<Person> &gt;&gt;到地图 <Integer, Map<String, Integer> &gt;? - Using Java 8 streams, how to transform Map<String, Map<String, List<Person>>> to Map<Integer, Map<String, Integer>>? 转换 Map <string,list<person> &gt; 至 Map <string,list<employee> &gt;,使用 Java 8 个流。 我这样做了,但是没有 for 循环怎么做</string,list<employee></string,list<person> - Convert Map<String,List<Person>> to Map<String,List<Employee>>, using Java 8 streams. I did this but how do this without for loop Java 流将字符串拆分和收集到 Map - Java streams to split and collect string to a Map 映射值通过流收集到字符串 - Map values collect to string with streams 如何转换清单 <DataObject> 到地图 <Integer, String> 使用流 - How to convert List<DataObject> to Map<Integer, String> using streams 将对象列表转换为地图 <String,Map<String,Integer> &gt; java8流 - convert list of object into a map of <String,Map<String,Integer>> java8 streams 如何生成列表的 Map 的 Map(地图<string, map<enum, list<string> &gt;&gt;) 在 java 中使用流</string,> - How do I generate a Map of Map of List (Map<String, Map<Enum, List<String>>>) in java using streams Java 流收集到 Map <String, Map<Integer, MyObject> &gt; - Java stream collect to Map<String, Map<Integer, MyObject>> 如何转换流 <Map<Integer, String> &gt;来映射java 8 - How to convert Stream<Map<Integer, String>> to map java 8 Java Streams:关于收集到Map <String,Object>的问题 - Java Streams: Issue about collect to a Map<String, Object>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM