黄河之水天上来,奔流到海不复回。Java中的流好比是河水,取值无尽,用之无竭,流是无尽的,我们通过流生成的元素进行复杂的计算。这里主要是记录一下使用方式,我们可以通过常用的数据结构创建流,并对数据进行筛选过滤,数据映射处理,后再进行数据的匹配输出,和通过使用for循环、调用函数方法等方式相比,该方式操作更加简洁、高效。
流的创建
我们可以通过集合、数组、字符串、文件流等方式创建流。
集合创建方式
通过Collection下的stream()和parallelStream()方法
🏳️🌈示例如下:
List
Stream
Stream
数组创建方式
🏳️🌈示例如下
Integer[] nums = new Integer[10];
Stream
Stream中的静态方法
使用of方法
Stream
使用iterate方法
Stream
使用generate方法
Stream
文件流的创建方式
使用BufferedReader.lines() 中的静态方法
BufferedReader reader = new BufferedReader(new FileReader("F:\test_stream.txt"));
Stream
lineStream.forEach(System.out::println);
字符串方式创建流
使用Pattern.splitAsStream()方法,将字符串分割成流
Pattern pattern = Pattern.compile(",");
Stream
stringStream.forEach(System.out::println);
流的中间操作
将数据结构转换为流,我们可以对流上的数据进行处理,处理方式包括数据筛选,排序,以及通过函数进行映射操作。个人觉得这也是流的好处之一,通过该方式简化了很多冗余的代码编写。
筛选与切片
通过该方式实现简单的数据操作
过滤(filter)
Stream
Stream newStream = stream.filter(s->s>5);
newStream.forEach(System.out::println);
去重(distinct)
Stream
Stream newStream = stream.distinct();
newStream.forEach(System.out::println);
获取n个元素
Stream
Stream newStream = stream.limit(3);
newStream.forEach(System.out::println);
跳过n个元素
Stream
Stream newStream = stream.skip(3);
newStream.forEach(System.out::println);
映射
通过流进行函数映射转换。
Map
map:接收一个函数作为参数,该函数将映射到每一个元素上,将其映射成为一个新的元素
List
Stream
s1.forEach(System.out::println);
Peek
Peek:如同map,但是没有返回值
Student s1 = new Student("aa", 10);
Student s2 = new Student("bb", 20);
List
studentList.stream() .peek(o -> o.setAge(100)).forEach(System.out::println);
//结果:
Student{name='aa', age=100}
Student{name='bb', age=100}
flatMap
flatMap:接受一个函数作为参数,将流中的每个值都换成另一个流,并将所有的流连接
List
Stream s4 = list.stream().flatMap(s->{String[] split = s.split(",") Stream
return s2; });
s4.forEach(System.out::println);
排序
通过流实现数据结构的排序
自然排序
自然排序,流中的元素需要实现Comparable接口
List
list.stream().sorted().forEach(System.out::println);
定制排序
定制排序,自定义Comparator排序器
Student s1 = new Student("aa", 10);
Student s2 = new Student("bb", 20);
Student s3 = new Student("aa", 30);
Student s4 = new Student("dd", 40);
List
//自定义排序:先按姓名升序,姓名相同则按年龄升序
studentList.stream().sorted(
(o1, o2) -> {
if (o1.getName().equals(o2.getName())) {
return o1.getAge() - o2.getAge();
} else {
return o1.getName().compareTo(o2.getName());
}
}
).forEach(System.out::println);
流的终止操作
通过流进行了数据的中间操作后,需要通过流进行匹配输出
匹配操作
allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
聚合操作
findFirst:返回流中第一个元素
findAny:返回流中的任意元素
count:返回流中元素的总个数
max:返回流中元素最大值
min:返回流中元素最小值
规约操作
相当于是循环操作执行,如1,2,3,4,5.则为1+2,3+3,6+4.....
收集操作
接收一个Collector实例,将流中元素收集成另外一个数据结构
//装成list
List