Java中使用StreamAPI将对象List转Map的几种情景

发布时间 2023-09-02 16:23:28作者: 偷师学艺小b仔汁

1.使用对象中的属性构建映射Map

假设一个对象Person,其中有id、name两个属性,并且有对应关系。

    @Data
    @AllArgsConstructor
    static class Person {
        private String id;
        private String Name;
    }

现在将一个List<Person>转变为id与name的Map<String,String>。
如果personList中存在相同id的两个或多个对象,构建Map时会抛出key重复的异常,需要设置一个合并方法,将value合并(也可以是其他处理)

        List<Person> personList = new ArrayList<>();
        personList.add(new Person("1","张三"));
        personList.add(new Person("1","李四"));
        personList.add(new Person("1","王五"));
        personList.add(new Person("2","王五"));
        personList.add(new Person("3","赵六"));
        Map<String,String> map = personList.stream()
                .collect(Collectors.toMap(Person::getId,Person::getName,(v1,v2) -> v1 + '-' + v2));
        System.out.println(map);

image

2.根据对象自定义Map中的Key与Value

代码:

        Map<String,String> map = personList.stream()
                .collect(Collectors.toMap(
                        item -> "编号:" + item.getId(),
                        item -> item.getName()+item.getId(),
                        (v1,v2) -> v1 + '-' + v2));
        map.forEach((key,value) -> {
            System.out.println(key+"\t"+value);
        });

结果:
image

3.对象List先分组再映射为Map<key,List<Obj>>

假设Person对象中多个属性groupNo

private Integer groupNo;

根据Person中的groupNo属性将原始List分组,并返回Map<groupNo,List<Person>>

        List<Person> personList = new ArrayList<>();
        personList.add(new Person("1","张三",1));
        personList.add(new Person("1","李四",1));
        personList.add(new Person("1","王五",2));
        personList.add(new Person("2","王五",2));
        personList.add(new Person("3","赵六",3));
        Map<Integer,List<Person>> map = personList.stream()
                .collect(Collectors.groupingBy(Person::getGroupNo));

image

3.1 多个属性组合分组

再给Person类加一个性别 gender属性

private String  gender;
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("1","张三",1,"男"));
        personList.add(new Person("1","李四",1,"女"));
        personList.add(new Person("1","王五",2,"男"));
        personList.add(new Person("2","王五",2,"变性人"));
        personList.add(new Person("3","赵六",3,"武装直升机"));
        Map<String,List<Person>> map = personList.stream()
                .collect(Collectors.groupingBy(item -> item.getGroupNo()+"--"+item.getGender()));
        map.forEach((key,value) -> {
            System.out.println(key+"\t\t"+value);
        });

image

3.2 分组后自定义Map中的Value

仅根据性别分组,并且Value只想要该分组的名称集合。实现如下

        Map<String,List<String>> map = personList.stream()
                .collect(Collectors.groupingBy(Person::getGender,Collectors.mapping(Person::getName,Collectors.toList())));

结果:
image