如何使用Java 8按条件遍历List并修改对象属性存入新List?
如何用Java 8按条件遍历List并将处理后的对象存入新List?
针对你的需求——仅当Employee的id等于100时,将其internalMark设置为externalMark与原internalMark之和,externalMark设为0,其余对象保持不变——我们可以通过Java 8的Stream API优雅实现,同时需要注意是否修改原对象的问题(引用类型的特性会导致直接修改原对象时,原List的数据也会被改变)。
初始代码的问题
你的现有代码存在几个关键问题:
- 未实现
internalMark = 原internalMark + externalMark的核心逻辑 - 直接修改原
Employee对象,会污染原List中的数据(原List里的id=100对象也会被修改) - 使用
forEach手动添加元素到新List,不符合Stream API的函数式编程风格 - 多余的
e.getId() > 0判断(id=100已经满足大于0,无需额外校验)
方案1:创建新对象(推荐,保持原数据不可变)
这是函数式编程的最佳实践,通过创建新对象来避免修改原数据,保证原List的完整性。
import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class Demo { public static void main(String[] args) { List<Employee> employees = Arrays.asList( new Employee(100, 500, "John", 250), new Employee(101, 500, "Jane", 250), new Employee(102, 500, "Jack", 250), new Employee(103, 500, "Mike", 250) ); // 用Stream的map转换元素,collect收集为新List List<Employee> newList = employees.stream() .map(emp -> { if (emp.getId() == 100) { // 为符合条件的对象创建新实例,赋值处理后的属性 return new Employee( emp.getId(), emp.getInternalMark() + emp.getExternalMark(), emp.getName(), 0 ); } // 其余对象直接返回原实例(或也创建新实例,根据需求决定) return emp; }) .collect(Collectors.toList()); System.out.println(newList); // 验证原List未被修改 System.out.println("原List的id=100对象:" + employees.get(0)); } static class Employee { private int id; private int internalMark; private String name; private int externalMark; public Employee() {} public Employee(int id, int internalMark, String name, int externalMark) { this.id = id; this.internalMark = internalMark; this.name = name; this.externalMark = externalMark; } // Getter和Setter方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public int getInternalMark() { return internalMark; } public void setInternalMark(int internalMark) { this.internalMark = internalMark; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getExternalMark() { return externalMark; } public void setExternalMark(int externalMark) { this.externalMark = externalMark; } @Override public String toString() { return "Employee [id=" + id + ", internalMark=" + internalMark + ", name=" + name + ", externalMark=" + externalMark + "]"; } } }
方案2:修改原对象(不推荐,会污染原数据)
如果业务场景明确允许修改原List中的对象,可以直接在Stream中修改属性,但要注意原数据会被改变:
import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class Demo { public static void main(String[] args) { List<Employee> employees = Arrays.asList( new Employee(100, 500, "John", 250), new Employee(101, 500, "Jane", 250), new Employee(102, 500, "Jack", 250), new Employee(103, 500, "Mike", 250) ); List<Employee> newList = employees.stream() .map(emp -> { if (emp.getId() == 100) { // 直接修改原对象的属性 emp.setInternalMark(emp.getInternalMark() + emp.getExternalMark()); emp.setExternalMark(0); } return emp; }) .collect(Collectors.toList()); System.out.println(newList); // 原List的id=100对象已被修改 System.out.println("原List的id=100对象:" + employees.get(0)); } // Employee类同方案1,省略重复代码 }
两种方案对比
- 方案1:无副作用,原数据不受影响,符合函数式编程的设计思想,适合绝大多数场景。
- 方案2:有副作用,原List的数据会被修改,仅在明确允许修改原数据时使用。
内容的提问来源于stack exchange,提问作者PAA
相关产品推荐
相关产品推荐

