目录
一、Stream流的概述
1、什么是Stream流?
2、Stream流的实现步骤
3、案例:体验Stream流的作用
3.1、需求
3.2、实现步骤
3.3、不使用stream流的代码
3.4、结果体现
3.5、使用stream流的代码
3.6、结果体现
二、Stream流的获取
1、集合获取Stream流的方式?
2、数组获取Stream流的方式?
三、Stream流的常用方法
1、Stream流的常用非终结操作方法
2、Stream流的常见终结操作方法
四、Stream流的综合应用
1、需求
2、分析
3、代码
4、结果
五、收集Stream流
答:在Java 8中,得益于Lambda所带来的函数式编程, 引入了一个全新的Stream流概念。
目的:用于简化集合和数组操作的API。
第一步:先得到集合或者数组的Stream流(就是一根传送带)
第二步:把元素放上去
第三步:然后就用这个Stream流简化的API来方便的操作元素。
按照下面的要求完成集合的创建和遍历
第一步:创建一个集合,存储多个字符串元素。
第二步:把集合中所有以"张"开头的元素存储到一个新的集合
第三步:把"张"开头的集合中的长度为3的元素存储到一个新的集合
第四步:遍历上一步得到的集合中的元素输出。
public class StreamTest {
public static void main(String[] args) {
List names = new ArrayList<>();
Collections.addAll(names,"张三分","张无忌","张强","赵名","周芷若");
System.out.println(names);
//1、从集合中找出姓张的放到新集合
List zhanglist = new ArrayList<>();
for (String name : names) {
if (name.startsWith("张")){
zhanglist.add(name);
}
}
System.out.println(zhanglist);
//2、找名称长度是3的姓名
List zhangThreeList = new ArrayList<>();
for (String s : zhanglist) {
if (s.length() == 3){
zhangThreeList.add(s);
}
}
System.out.println(zhangThreeList);
}
}
public class StreamTest {
public static void main(String[] args) {
List names = new ArrayList<>();
Collections.addAll(names,"张三分","张无忌","张强","赵名","周芷若");
System.out.println(names);
//names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
names.stream().filter(s -> s.startsWith("张") && s.length() == 3).forEach(s -> System.out.println(s));
}
}
答:可以使用Collection接口中的默认方法stream()生成流。
名称 |
说明 |
default Stream |
获取当前集合对象的Stream流 |
代码:
/**--------------------------Collectio集合获取Stream流---------------*/
Collection list = new ArrayList<>();
Stream s = list.stream();
/**--------------------------Map集合获取Stream流---------------*/
Map map =new HashMap<>();
//键流
Stream keyStream = map.keySet().stream();
//值流
Stream valuesStream = map.values().stream();
//键值对(拿整体)
Stream> keyAndValueStream = map.entrySet().stream();
名称 |
说明 |
public static |
获取当前数组的Stream流 |
public static |
获取当前数组/可变数据的Stream流 |
代码:
/**--------------------------数组获取Stream流---------------*/
String[] names = {"张无忌", "小花", "小王"};
Stream ss = Arrays.stream(names);
Stream ss1 = Stream.of(names);
常见方法:
名称 |
说明 |
Stream |
用于对流中的数据进行过滤。 |
Stream |
获取前几个元素 |
Stream |
跳过前几个元素 |
Stream |
去除流中重复的元素。依赖(hashCode和equals方法) |
static |
合并a和b两个流为一个流 |
注意:
中间方法也称为非终结方法,调用完成后返回新的Stream流可以继续使用,支持链式编程。
在Stream流中无法直接修改集合、数组中的数据。
常见方法:
名称 |
说明 |
void forEach(Consumer action) |
对此流的每个元素执行遍历操作 |
long count() |
返回此流中的元素数 |
注意:终结操作方法,调用完成后流就无法继续使用了,原因是不会返回Stream了。
某个公司的开发部门,分为开发一部和二部,现在需要进行年中数据结算。
2.1:员工信息至少包含了(名称、性别、工资、奖金、处罚记录)
2.2:开发一部有4个员工、开发二部有5名员工
2.3:分别筛选出2个部门的最高工资的员工信息,封装成优秀员工对象Topperformer
2.4:分别统计出2个部门的平均月收入,要求去掉最高和最低工资。
2.5:统计2个开发部门整体的平均工资,去掉最低和最高工资的平均值。
public class StreamDemo04 {
public static double allmoney1 = 0;
public static double allmoney2 = 0;
public static double allmoney3 = 0;
public static void main(String[] args) {
List one = new ArrayList<>();
one.add(new Employee("猪八戒", '男', 30000, 25000, null));
one.add(new Employee("孙悟空", '男', 25000, 1000, "顶撞上司" ));
one.add(new Employee("沙僧", '男', 20000, 20000, null));
one.add(new Employee("小白龙", '男', 20000, 25000, null));
List two = new ArrayList<>();
two.add(new Employee("武松", '男', 15000, 9000, null));
two.add(new Employee("李逵", '男', 20000, 10000, null ));
two.add(new Employee("西门庆", '男', 50000, 100000, "被打"));
two.add(new Employee("潘金莲", '女', 3500, 1000, "被打"));
two.add(new Employee("武大郎", '男', 20000, 0, "下毒"));
//1、开发一部,最高工资的员工
//指定大小规则
// Employee e = one.stream().max((e1,e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus()))
// .get();
// System.out.println(e);
Topperformer t = one.stream().max((e1,e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus()))
.map(e -> new Topperformer(e.getName(), e.getSalary() + e.getBonus())).get();
System.out.println(t);
//2、统计平均工资,去掉最高工资和最低工资(开发一部)
one.stream().sorted((e1,e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus()))
.skip(1).limit(one.size() - 2).forEach(e -> {
//求出总和:剩余员工的工资总和
allmoney1 += (e.getSalary() + e.getBonus());
});
System.out.println("开发一部的平均工资为:"+allmoney1/(one.size()-2));
//3、统计平均工资,去掉最高工资和最低工资(开发二部)
two.stream().sorted((e1,e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus()))
.skip(1).limit(two.size() - 2).forEach(e -> {
//求出总和:剩余员工的工资总和
allmoney2 += (e.getSalary() + e.getBonus());
});
//BigDecimal
BigDecimal b1 = BigDecimal.valueOf(allmoney2);
BigDecimal b2 = BigDecimal.valueOf(two.size()-2);
System.out.println("开发二部的平均工资为:"+b1.divide(b2,2, RoundingMode.HALF_UP));
//4、统计平均工资,去掉最高工资和最低工资(开发二部和开发一部)
Stream s1 = one.stream();
Stream s2 = two.stream();
Stream s3 = Stream.concat(s1,s2);
s3.sorted((e1,e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus()))
.skip(1).limit(one.size() + two.size() - 2).forEach(e -> {
//求出总和:剩余员工的工资总和
allmoney3 += (e.getSalary() + e.getBonus());
});
//BigDecimal
BigDecimal b3 = BigDecimal.valueOf(allmoney3);
BigDecimal b4 = BigDecimal.valueOf(one.size() + two.size()-2);
System.out.println("开发一部和开发二部的平均工资为:"+b3.divide(b4,2, RoundingMode.HALF_UP));
}
}
1、收集Stream流的含义:就是把Stream流操作后的结果数据转回到集合或者数组中去。
2、Stream流:方便操作集合/数组的手段。
3、集合/数组:才是开发中的目的。
4、Stream流的收集方法
名称 |
说明 |
R collect(Collector collector) |
开始收集Stream流,指定收集器 |
5、 Collectors工具类提供了具体的收集方式
名称 |
说明 |
public static |
把元素收集到List集合中 |
public static |
把元素收集到Set集合中 |
public static Collector toMap(Function keyMapper , Function valueMapper) |
把元素收集到Map集合中 |
6、代码
public static void main(String[] args) {
List list1 = new ArrayList<>();
list1.add("张无忌");
list1.add("周芷若");
list1.add("赵明");
list1.add("张强");
list1.add("张三风");
list1.add("张三风");
//收集List集合
Stream s1 = list1.stream().filter(s -> s.startsWith("张"));
List zhanglist = s1.collect(Collectors.toList()); //可变集合
zhanglist.add("Java1");
System.out.println(zhanglist);
// List list2 = s1.toList(); //得到不可变集合
// list2.add("Java");
// System.out.println(list1);
//注意:流只能使用一次
//收集Set集合
Stream s2 = list1.stream().filter(s -> s.startsWith("张"));
Set zhanglist1 = s2.collect(Collectors.toSet());
System.out.println(zhanglist1);
Stream s3 = list1.stream().filter(s -> s.startsWith("张"));
// Object[] objects = s3.toArray();
String[] s = s3.toArray(String[]::new);//定义一个字符串类型的数组
System.out.println(Arrays.toString(s));
}
7、结果展示