一、前言
在实际的开发过程中,还有一个使用最频繁的操作就是,将集合元素中某个主键字段作为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;
}
}
程序运行:
在 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));
}
}
程序运行:
打开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
的内容作为key
,v -> 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;
}
}
程序运行:
而在 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()));
}
}
程序运行: