开幕先看代码
List<Hero> heroes = StreamListDemo01.heroValues();
List<Salarys> salarysValues = StreamListDemo01.salarysValues();
for (Hero hero : heroes) {
if (salarysValues.size()>0) {
for (Salarys salarysValue : salarysValues) {
if (hero.getId()==salarysValue.getId()) {
hero.setSalary(salarysValue.getSalary());
break;
}
hero.setSalary(0.0F);
}
}else{
hero.setSalary(0.0F);
}
}
复制代码
需求是这个样子的
是要为一个 Hero 集合中的每个对象,赋予一个匹配的 Salarys 对象中的 salary 值。具体实现方式为遍历 Hero 集合,对于每一个 Hero 对象,遍历 Salarys 集合,只有当 Hero 对象的 ID 与 Salarys 对象的 ID 匹配时,才将 Salarys 对象的 salary 值赋值给 Hero 的 salary 属性。如果 Hero 的 ID 没有匹配成功,则将 Hero 的 salary 属性设置为 0.0F。如果 Salarys 集合为空,则将 Hero 的 salary 属性设置为 0.0F。
虽然通过嵌套 for 搞定了,但是我想把这玩意搞成 Java8 Stream 写法的!接下让我们开始看逐步拆解吧。
思路概述
将 heroes 转换为 Stream 对象;
使用 peek 操作设置所有 hero 的初始 salary 为 0;
对 heroes 进行 forEach 操作,对于每个 hero,将 salarysValues 转换为 Stream 对象;
使用 filter 操作筛选出符合条件的 salary(即 id 匹配);
使用 findFirst 操作获取第一个匹配结果(如果有的话);
如果有匹配结果,则使用 ifPresent 操作将 salary 的值赋给该 hero 的 salary 属性。若无匹配结果,则 salary 仍为初始值 0。
步骤详解
将 heroes 转换为 Stream 对象
将 heroes 集合对象转换为 Stream 对象,可以使用以下方式:
使用 peek 操作设置所有 hero 的初始 salary 为 0
使用 peek 方法来实现操作了,peek 方法会遍历集合中的每一个元素,可以对每个元素进行操作并返回一个 Stream 对象。
.peek(hero -> hero.setSalary(0.0F))
复制代码
对 heroes 进行 forEach 操作,对于每个 hero,将 salarysValues 转换为 Stream 对象
在 forEach 方法中对每个 hero 进行操作,对于每个 hero,需要将另一个集合 salarysValues 转换为 Stream 对象,可以使用以下操作:
.forEach(hero -> {
salarysValues.stream()
复制代码
使用 filter 操作筛选出符合条件的 salary(即 id 匹配)
对于 salarysValues 集合中元素的筛选,需要通过 filter 操作进行筛选。filter 方法返回一个 Stream,由于我们只需要一个结果,因此使用 findFirst 方法获取第一个结果。
.filter(salary -> hero.getId() == salary.getId())
复制代码
该代码会对 salarysValues 集合中的每个元素进行比较操作,将符合条件的元素返回作为一个新的 Stream,只有符合条件的元素才会继续执行下面的操作。使用 lambda 表达式的方式,将当前 hero 的 id 和 salarysValues 集合中的 id 进行比较,如果相同,则返回 true。
使用 findFirst 操作获取第一个匹配结果(如果有的话)
使用 findFirst 方法获取第一个匹配的结果,如果有分配的 Salary,则第一个匹配结果应该是分配到该 Hero 的 Salary。findFirst 方法返回一个 Optional 对象,Optional 封装了要返回对象可能为空的情况。
如果有匹配结果,则使用 ifPresent 操作将 salary 的值赋给该 hero 的 salary 属性。若无匹配结果,则 salary 仍为初始值 0。
使用 ifPresent 方法,如果结果不为空(存在匹配结果),就将结果设置给该 Hero 的 Salary,如果不存在匹配结果,则该 Hero 的 Salary 属性值不被改变,即为初始值 0。
.ifPresent(salary -> hero.setSalary(salary.getSalary()));
hero.setSalary(0.0F); // 设置Hero的薪水属性初始值为0
复制代码
完整 stream 代码示例:
heroes.stream()
.peek(hero -> hero.setSalary(0.0F)) // 设置所有hero的初始salary为0
.forEach(hero -> {
salarysValues.stream()
.filter(salary -> hero.getId() == salary.getId()) // 筛选出符合条件的salary
.findFirst() // 获取第一个匹配结果(如果存在)
.ifPresent(salary -> hero.setSalary(salary.getSalary())); // 将匹配到的salary的值赋给hero
hero.setSalary(0.0F); // 如果不存在匹配结果,设置薪水初始值为0
});
复制代码
完整示例代码
public class StreamListDemo01 {
private static List<Hero> heroValues(){
List<Hero> heroes = new ArrayList<>();
for (int i = 1; i < 10; i++) {
Hero hero = new Hero();
hero.setId(i);
hero.setName("张三"+i);
heroes.add(hero);
}
return heroes;
}
private static List<Salarys> salarysValues(){
List<Salarys> salarysList = new ArrayList<>();
for (int i = 1; i < 5; i++) {
Salarys salarys = new Salarys();
salarys.setId(i);
salarys.setSalary(1.4F+i);
salarysList.add(salarys);
}
return salarysList;
}
public static void main(String[] args) {
List<Hero> heroes = StreamListDemo01.heroValues();
List<Salarys> salarysValues = StreamListDemo01.salarysValues();
for (Hero hero : heroes) {
if (salarysValues.size()>0) {
for (Salarys salarysValue : salarysValues) {
if (hero.getId()==salarysValue.getId()) {
hero.setSalary(salarysValue.getSalary());
break;
}
hero.setSalary(0.0F);
}
}else{
hero.setSalary(0.0F);
}
}
heroes.stream()
.peek(hero -> hero.setSalary(0.0F)) // 设置所有hero的初始salary为0
.forEach(hero -> {
salarysValues.stream()
.filter(salary -> hero.getId() == salary.getId())
.findFirst()
.ifPresent(salary -> hero.setSalary(salary.getSalary())); // 将匹配到的salary的值赋给hero
});
System.out.println(heroes);
}
}
class Hero{
private String Name;
private int Id;
private Float Salary;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public Float getSalary() {
return Salary;
}
public void setSalary(Float salary) {
Salary = salary;
}
@Override
public String toString() {
return "Hero{" +
"Name='" + Name + '\'' +
", Id=" + Id +
", Salary=" + Salary +
'}';
}
}
class Salarys{
private int Id;
private Float Salary;
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public Float getSalary() {
return Salary;
}
public void setSalary(Float salary) {
Salary = salary;
}
@Override
public String toString() {
return "Salarys{" +
"Id=" + Id +
", Salary=" + Salary +
'}';
}
}
复制代码
评论