一个将学生对象(年龄、姓名、学号)的List转换为Map
package Test1;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ConvertStream {
public static void main(String[] args) {
List students = new ArrayList<>();
students.add(new Student(16, "zhangSan", 1));
students.add(new Student(17, "liSi", 2));
students.add(new Student(18, "wangWu", 3));
students.add(new Student(19, "kk", 4));
Map studentMap = students.stream()
.collect(Collectors.toMap(Student::getSno,Student::getName));
System.out.println(studentMap);
}
static class Student {
public Student(int age, String name, int sno) {
this.age = age;
this.name = name;
this.sno = sno;
}
int age;
String name;
int sno;
public String getName() {
return name;
}
public int getSno() {
return sno;
}
}
}
这里使用了stream的API
使用 students.stream()
将学生列表转换为 Stream 对象。接下来调用 collect
方法,并传入 Collectors.toMap
来进行转换。
(Collectors.toMap
是用来将流转换为 Map 的收集器。它接受两个参数:键提取函数和值提取函数,以及一个可选的合并函数。
keyMapper
:一个用于从流中的元素中提取键的函数。这个函数将会被应用到流中的每个元素上。valueMapper
:一个用于从流中的元素中提取值的函数。这个函数将会被应用到流中的每个元素上。mergeFunction
(可选):一个用于解决键冲突的合并函数。当两个元素具有相同的键时,该函数将被调用,并提供了两个值作为参数,以确定最终的值。这个示例中,使用了以下参数:
Student::getSno
,将学生对象的学号作为键。Student::getName
,将学生对象的姓名作为值。 由于没有指定合并函数,当遇到学号相同的学生时,会抛出 java.lang.IllegalStateException
异常。这意味着在给定的学生列表中,学号必须是唯一的。
如果想要处理键冲突的情况,可以提供一个合适的合并函数作为 toMap
方法的第三个参数,以处理键相同的情况,例如:
Map studentMap = students.stream() .collect(Collectors.toMap(Student::getSno, Student::getName, (oldValue, newValue) -> newValue));
)
在 Collectors.toMap
方法中,通过方法引用 Student::getSno
和 Student::getName
指定了键和值的提取方式。即将学号作为键,姓名作为值。
先创建几个实例
pigs.add(new Pig(1, "pig1", 31, "M", false));
pigs.add(new Pig(2, "pig2", 28, "F", true));
pigs.add(new Pig(3, "pig3", 2, "M", false));
pigs.add(new Pig(4, "pig4", 5, "F", false));
Map mapById = pigs.stream()
.collect(
Collectors.toMap(
Pig::getId,
a -> a,
(k1, k2) -> k1)//如果id相同,取第1个
);
mapById.forEach((k, v) -> {
System.out.println(k + " -> " + v.toString());
});
其中
stream()
:将 List 转换为 Stream。collect()
:将 Stream 中的元素收集到一个结果容器中。Collectors.toMap()
:使用提供的键和值映射函数将 Stream 元素收集到一个 Map 中。Pig::getId
:用于提取 Pig
对象的 id
作为键。a -> a
:用于指定将每个 Pig
对象本身作为值。(k1, k2) -> k1
:用于指定当发现相同的键时,选择保留第一个出现的 Pig
对象作为值。最后,通过 mapById.forEach()
循环遍历并打印 Map
中的键值对:
(k, v) -> { System.out.println(k + " -> " + v.toString()); }
是一个 lambda 表达式,用于迭代并打印 mapById
中的每个键值对。k
代表键,v
代表值。
这就是 (k, v)
来源的地方。在 mapById.forEach()
方法中,我们使用 lambda 表达式来定义一个函数,该函数接受两个参数 k
和 v
,并在每次迭代时被调用。
在每次迭代中,将键和值传递给 lambda 表达式,并在控制台上打印出键和对应的值的字符串表示。
结果大致如下
1 -> Pig(id=1, name=pig1, age=31, gender=M, valid=false)
2 -> Pig(id=2, name=pig2 age=28, gender=F, valid=true)
3 -> Pig(id=3, name=pig3, age=2, gender=M, valid=false)
4 -> Pig(id=4, name=pig4, age=5, gender=F, valid=false)