下面是Employee类。
public static class Employee {
private String name;
private int age;
private int salary;
// constructor, getters, setters, etc.
}有一份员工名单。
我需要得到age大于或等于32年的员工名单,然后通过50%增加他们的salary,并将这些员工收集到一个新的列表中。
样本数据:
List<Employee> el = new ArrayList<Employee>();
el.add(new Employee("A",30,3000));
el.add(new Employee("B",32,3000));
el.add(new Employee("C",33,5000));我的尝试:
el.stream()
.filter(i -> i.getAge() >= 32)
.map(i -> i.getSalary() *3 / 2)
.collect(Collectors.toList());但这是返回一个整数类型的列表- List<Integer>。相反,我希望返回的列表是一个员工类型的列表- List<Employee>。
发布于 2022-09-05 19:58:23
改变流中元素的状态不是一个好的实践。
相反,可以使用流筛选具有目标年龄的员工。然后使用Iterable.forEach()方法进行薪资变更。
List<Employee> employeeOlder32 = el.stream()
.filter(i -> i.getAge() >= 32)
.toList(); // for Java 16+ or collect(Collectors.toList()) for earlier versions
employeeOlder32.forEach(employee ->
employee.setSalary(employee.getSalary() * 3 / 2)
);Sidenote:一种常见的做法是使用BigDecimal来表示价格、薪水等(而不是int或double)。
发布于 2022-09-05 17:39:46
您不能在流中修改数据,最终需要创建新的列表并在其中存储已操作的数据。
List<Employee> newList = el.stream()
.map(f -> new Employee(f.getName(),f.getAge(), f.setSalary((f.getSalary()*3)/2)))
.collect(Collectors.toList());发布于 2022-09-05 23:29:12
另外两个答案都说,您不应该也不能更改正在流的对象。据我所知,那条指令是错误的。我怀疑它们混淆了不应该修改正在流的集合的 structure 的规则,例如向源列表中添加/删除对象。可以修改集合元素的内容。
边流边修改对象
在流列表时,在每个Employee对象元素上调用Employee#setSalary以更新新计算的值。
使用扩展表示法,代码的关键部分如下。
在流列表时,我们使用Stream#forEach对每个元素运行一些代码。
将int字段salary乘以float类型将得到float值。调用Math.round会将其转换为int。
employees
.stream()
.forEach (
( Employee employee ) ->
{
employee.setSalary (
Math.round( employee.getSalary () * 1.5F )
);
}
)
;下面是使用紧凑表示法的完整示例。
为了方便起见,我们使用List.of生成文本语法中不可修改的列表。
List < Employee > employees = List.of(
new Employee( "Alice" , 30 , 3000 ) ,
new Employee( "Bob" , 32 , 3000 ) ,
new Employee( "Carol" , 33 , 5000 )
);
System.out.println( "Before: " + employees );
employees.stream().forEach( employee -> employee.setSalary( Math.round( employee.getSalary() * 1.5F ) ) );
System.out.println( "After: " + employees );结果:
Before: [Employee[name=Alice, age=30, salary=3000], Employee[name=Bob, age=32, salary=3000], Employee[name=Carol, age=33, salary=5000]]
After: [Employee[name=Alice, age=30, salary=4500], Employee[name=Bob, age=32, salary=4500], Employee[name=Carol, age=33, salary=7500]]只是FYI,下面是上面使用的Employee类。没什么意思。
package work.basil.example.modstream;
import java.util.Objects;
public final class Employee
{
// Member fields.
private String name;
private int age;
private int salary;
// Constructor
public Employee ( String name , int age , int salary )
{
this.name = name;
this.age = age;
this.salary = salary;
}
// Accessors
public String getName ( ) { return name; }
public void setName ( final String name ) { this.name = name; }
public int getAge ( ) { return age; }
public void setAge ( final int age ) { this.age = age; }
public int getSalary ( ) { return salary; }
public void setSalary ( final int salary ) { this.salary = salary; }
// `Object` overrides.
@Override
public boolean equals ( Object obj )
{
if ( obj == this ) { return true; }
if ( obj == null || obj.getClass() != this.getClass() ) { return false; }
var that = ( Employee ) obj;
return Objects.equals( this.name , that.name ) &&
this.age == that.age &&
this.salary == that.salary;
}
@Override
public int hashCode ( )
{
return Objects.hash( name , age , salary );
}
@Override
public String toString ( )
{
return "Employee[" +
"name=" + name + ", " +
"age=" + age + ", " +
"salary=" + salary + ']';
}
}https://stackoverflow.com/questions/73611442
复制相似问题