例题
使用集合Stream完成下列需求
需求:某个公司的开发部门,分为开发一部和二部,现在需要进行年中数据结算。
分析:
:员工信息至少包含了(名称、性别、工资、奖金、处罚记录)
:开发一部有4个员工、开发二部有5名员工
:分别筛选出2个部门的最高工资的员工信息,封装成优秀员工对象Topperformer
:分别统计出2个部门的平均月收入,要求去掉最高和最低工资。
:统计2个开发部门整体的平均工资,去掉最低和最高工资的平均值。
package HomeWork1;
import java.util.*;
public class Test {
public static void main(String[] args) {
List<Employee>employee2=new ArrayList();
List<Employee> employee1=new ArrayList();
employee1.add(new Employee("张三","男",3500,500,"无","开发一部"));
employee1.add(new Employee("李四","男",3600,600,"无","开发一部"));
employee1.add(new Employee("王五","男",3000,200,"迟到","开发一部"));
employee1.add(new Employee("赵六","男",3900,400,"无","开发一部"));
employee2.add(new Employee("李思思","女",3500,500,"无","开发二部"));
employee2.add(new Employee("黄","男",2500,50,"迟到早退","开发二部"));
employee2.add(new Employee("图图","男",4000,1000,"无","开发二部"));
employee2.add(new Employee("胡英俊","男",5000,1100,"无","开发二部"));
employee2.add(new Employee("张小丽","女",45000,900,"无","开发二部"));
Comparator<Employee> comparator =(e1,e2) -> (int) ((e1.getBound() + e1.getSalary()) - (e2.getBound() + e2.getSalary()));
Optional<Employee> optionalEmployee = employee1.stream().max(comparator);
Topperformer topperformer1=new Topperformer(optionalEmployee.get(),"开发一部");
System.out.println(topperformer1.toString());
Optional<Employee> optionalEmployee2 = employee2.stream().min(comparator);
Topperformer topperformer2=new Topperformer(optionalEmployee2.get(),"开发二部");
System.out.println(topperformer2.toString());
OptionalDouble average = employee1.stream().mapToDouble(epl -> epl.getBound() + epl.getSalary())
.skip(1)
.limit(employee1.size() - 2).average();
System.out.println(average.getAsDouble());
OptionalDouble average2 = employee2.stream().mapToDouble((epl2 -> epl2.getSalary() + epl2.getBound()))
.skip(1)
.limit(employee2.size() - 2)
.average();
System.out.println(average2.getAsDouble());
employee1.addAll(employee2);
OptionalDouble average3 = employee1.stream().mapToDouble(emp1 -> emp1.getBound() + emp1.getSalary())
.skip(1)
.limit(employee1.size() - 2)
.average();
System.out.println(average3.getAsDouble());
}
}
其中用到的stream流方法和知识点如下
一.stream流的定义
Stream
将要处理的元素集合看作一种流,在流的过程中,借助Stream API
对流中的元素进行操作,比如:筛选、排序、聚合等。
二.stream流中常用方法
stream流中的方法分为三种:获取stream流 中间方法 终结方法
获取Stream流方法:
1.如果是collection集合我们可以通过 .stream()方法来获取stream流
List<String> list = new ArrayList<>();
Stream<String> stream01 = list.stream();
2.字符串数组:
Stream<String> stream01 = Stream.of("aa", "bb", "cc"shu
3.数组类型(基本类型除外)
String[] strs = {"aa","bb","cc"};
Stream<String> stream07 = Stream.of(strs);
常用方法:
中间方法:
filter() 方法,用于过滤数据,返回符合过滤条件的数据,是一个非终结方法。我们可以通过 filter() 方法将一个流转换成另一个子集流。该接口接收一个 Predicate 函数式接口参数(可以是一个 Lambda 或 方法引用) 作为筛选条件。
Stream<T> filter(Predicate<? super T> predicate);
limit() 方法,用来对 Stream 流中的数据进行截取,只取用前 n 个,是一个非终结方法。参数是一个 long 型,如果集合当前长度大于参数则进行截取,否则不进行操作。因为 limit() 是一个非终结方法,所以必须调用终止方法。
Stream<T> limit(long maxSize);
如果希望跳过前几个元素,取后面的元素,则可以使用 skip()方法,获取一个截取之后的新流,它是一个非终结方法。参数是一个 long 型,如果 Stream 流的当前长度大于 n,则跳过前 n 个,否则将会得到一个长度为 0 的空流。因为 skip() 是一个非终结方法,所以必须调用终止方法
Stream<T> skip(long n);
map() 方法,可以将流中的元素映射到另一个流中。即:可以将一种类型的流转换为另一种类型的流,map() 方法是一个非终结方法。该接口需要一个 Function 函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流。
<R> Stream<R> map(Function<? super T, ? extends R> mapper);