@TOC
第一章:Stream流是什么
1.1)简单介绍
学习Stream流就绕不开Lambda表达式,
需要了解Lambda表达式可以看一下这篇–>:Lambda表达式学习
1.其实“流”是个抽象概念,我们把现实世界中与Stream流有相同特性的东西也称为“流”,比如水流,流水线。流的思想就像工厂中的“生产流水线”,将集合或数组中的元素当做流水线上的产品进行操作。
2.既然是操作计算数据那么这些数据的源头是什么?可以是数组、文件、集合、函数。注意:Stream流不保存数据,不是容器。更贴切的比喻是流水线,产品只是经过流水线而不保存在流水线上。
1.2)创建流的五种方式
①直接用方法创建
Stream s = Stream.of(1,2,3,4,5,6,7);
②根据集合创建
//创建集合
ArrayList<String> list = new ArrayList<>();
//添加元素
Collections.addAll(list,"张三","李四","张五极","张六六","张七八九");
//流对象创建
Stream<String> lisStream = list.Stream();
③根据数组,要注意数组存储的数据类型,这里生成的流是数值流。mapToInt、mapToDouble、mapToLong可以将对象流转换成对应的数值流,而boxed方法可以把数值流转换为对象流。
int[] intArr = {1,2,3,4,5,6};
// 因为是int数组 所以变成了IntStream
IntStream arrayStream = Arrays.stream(intArr);
④根据文件,通过Files.line方法,得到的每个流是给定文件中的一行
//这个是我百度的
try {
Stream<String> fileStream = Files.lines(Paths.get("data.txt"), Charset.defaultCharset());
} catch (IOException e) {
e.printStackTrace();
}
⑤函数创建
第一种函数iterate
方法接受两个参数,第一个为初始化值,第二个为进行的函数操作,因为iterator生成的流为无限流,通过limit方法对流进行了截断,只生成5个偶数
第二种函数generate
generate方法接受一个参数,方法参数类型为Supplier ,由它为流提供值。generate生成的流也是无限流,因此通过limit对流进行了截断
//第一种iterate
Stream<Integer> iterateStream = Stream.iterate(0, n -> n + 2).limit(5);
//第二种generate
Stream<Double> generateStream = Stream.generate(() -> Math.random()).limit(5);
第二章、Stream流的应用
Java8中提供了方便的一些流操作(比如过滤、排序之类的),从应用中体会Stream流,从案例中了解它的特点和应用场景
2.1)Stream流中的函数式接口Predicate
1.使用Stream流操作集合中的数据,创建集合后创建流对象
//创建集合
ArrayList<String> list = new ArrayList<>();
//添加元素
Collections.addAll(list,"张三","李四","张五极","张六六","张七八九");
//流对象创建
Stream<String> lisStream = list.Stream();
2.使用filter()方法,参数是函数式接口Predicate,所以可以使用Lambda表达式(不会的可以看文章开头有提到),方法介绍如下:
filter(Predicate<? super T> predicate) 返回由与此给定谓词匹配的此流的元素组成的流Stream<T> 。
//创建流对象
Stream<String> stream = list.stream();
//筛选所有姓张的人,并返回满足此条件的元素组成的流
Stream<String> stream1 = stream.filter(name -> name.startsWith("张"));
//筛选姓名长度为3个字符的人,并返回满足此条件的元素组成的流
Stream<String> stream2 = stream1.filter(name -> name.length() == 3);
//打印,forEach(Consumer<? super T> action) 方法,对此流的每个元素执行操作。
stream2.forEach(name -> System.out.println(name));
运行结果:
2.2)Stream流中的函数式接口Supplier
1.自定义方法 getDemo() ,传入的参数是函数式接口Supplier,使用getDemo方法时使用匿名内部类的写法,重写get()方法。
//java.util.function.Supplier<T>:生产型接口,代表结果供应商。
//(这里看着很绕,其实就是说不给参数也会给你一个结果)
//抽象方法T get() 获得结果。
public static void main(String[] args) {
//匿名内部类,重写get()方法
getDemo(new Supplier<String>() {
@Override
public String get() {
return "hello world";
}
});
// lambda
getDemo(()->{ return "HELLO WORLD";});
}
//自定义方法 getDemo() ,传入的参数是函数式接口Supplier
public static void getDemo(Supplier<String> supplier){
String s = supplier.get();
System.out.println("s = " + s);
}