掌握 java stream 流集合转Map操作

时间:2024-12-10 11:57:35

一、前言

在实际的开发过程中,还有一个使用最频繁的操作就是,将集合元素中某个主键字段作为key,元素作为value,来实现集合转map的需求,这种需求在数据组装方面使用的非常多,尤其是在禁止连表 sql 查询操作的公司,视图数据的拼装只能在代码层面来实现

二、集合转Map(不分组)

在 jdk7 中,将集合中的元素转 map,我们通常会采用如下方式。

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author qinxun
 * @date 2024/12/09 9:03
 * @dec
 **/
public class ListDemo {
    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student(1L, "aa", 20));
        studentList.add(new Student(2L, "bb", 21));
        studentList.add(new Student(3L, "cc", 22));

        Map<Long, Student> map = getStudentIds(studentList);
        System.out.println(map);
    }


    public static Map<Long, Student> getStudentIds(List<Student> studentList) {
        //将集合转换成Map,其中用户ID作为主键key
        Map<Long, Student> map = new HashMap<>();
        for (Student student : studentList) {
            map.put(student.getId(), student);
        }
        return map;
    }
}

程序运行:

掌握 java stream 流集合转Map操作_List

在 jdk8 中,采用 stream api的方式,我们只需要一行代码即可实现

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author qinxun
 * @date 2024/12/09 9:03
 * @dec
 **/
public class ListDemo {
    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student(1L, "aa", 20));
        studentList.add(new Student(2L, "bb", 21));
        studentList.add(new Student(3L, "cc", 22));
        studentList.add(new Student(2L, "bb", 21));

        Map<Long, Student> map = getStudentIds(studentList);
        System.out.println(map);
    }


    public static Map<Long, Student> getStudentIds(List<Student> studentList) {
        //将集合转换成Map,其中用户ID作为主键key
        return studentList.stream().collect(Collectors.toMap(Student::getId, v->v,(k1, k2)->k1));
    }
}

程序运行:

掌握 java stream 流集合转Map操作_List_02

打开Collectors.toMap方法源码,一起来看看到底是啥。

public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper,
                                BinaryOperator<U> mergeFunction) {
    return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}

从参数表可以看出:

  • 第一个参数:表示 key
  • 第二个参数:表示 value
  • 第三个参数:表示某种规则

上文中的Collectors.toMap(Student::getId, v -> v, (k1,k2) -> k1),表达的意思就是将userId的内容作为keyv -> v是表示将元素student作为value,其中(k1,k2) -> k1表示如果存在相同的key,将第一个匹配的元素作为内容,第二个舍弃!

三、集合转map(分组)

在实际的操作中,有一些场景需要我们将相同的key,加入到一个集合,而不是覆盖,哪改如何做呢?

如果是采用 jdk7,我们大概会这么做。

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author qinxun
 * @date 2024/12/09 9:03
 * @dec
 **/
public class ListDemo {
    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student(1L, "aa", 20));
        studentList.add(new Student(2L, "bb", 21));
        studentList.add(new Student(3L, "cc", 22));
        studentList.add(new Student(2L, "bb", 21));

        Map<Long, List<Student>> map = getStudents(studentList);
        System.out.println(map);
    }


    public static Map<Long, List<Student>> getStudents(List<Student> studentList) {
        //将集合转换成Map,将相同的key,加入到一个集合中,实现分组
        Map<Long, List<Student>> studentMap = new HashMap<>();
        for (Student student : studentList) {
            if (studentMap.containsKey(student.getId())) {
                studentMap.get(student.getId()).add(student);
            } else {
                List<Student> students = new ArrayList<>();
                students.add(student);
                studentMap.put(student.getId(), students);
            }
        }
        return studentMap;
    }
}

程序运行:

掌握 java stream 流集合转Map操作_System_03

而在 jdk8 中,采用 stream api的方式,我们只需要一行代码即可实现

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author qinxun
 * @date 2024/12/09 9:03
 * @dec
 **/
public class ListDemo {
    public static void main(String[] args) {
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student(1L, "aa", 20));
        studentList.add(new Student(2L, "bb", 21));
        studentList.add(new Student(3L, "cc", 22));
        studentList.add(new Student(2L, "bb", 21));

        Map<Long, List<Student>> map = getStudents(studentList);
        System.out.println(map);
    }


    public static Map<Long, List<Student>> getStudents(List<Student> studentList) {
        //将集合转换成Map,将相同的key,加入到一个集合中,实现分组
        return studentList.stream().collect(Collectors.groupingBy(s -> s.getId()));
    }
}

程序运行:

掌握 java stream 流集合转Map操作_System_03