一、Stream
Java 8 中的 Stream
是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。
二、 特点
- 只能遍历一次
- 采用内部迭代方式
- Stream不会修改源数据,无论怎么操作源数据并不会改变
- 惰性,延迟加载
- Stream可以执行并行操作
三、流的操作
-
中间操作
当数据源中的数据上了流水线后,这个过程对数据进行的所有操作都称为“中间操作”,中间操作仍然会返回一个流对象,因此多个中间操作可以串连起来形成一个流水线。常包含函数式接口:
1、 Consumer,消费接口
2、 Supplier,供给接口
3、 Function,函数型接口
4、 Predicate,断言型接口 -
终端操作
当所有的中间操作完成后,若要将数据从流水线上拿下来,则需要执行终端操作 ,终端操作将返回一个执行结果,这就是你想要的数据。
过程:获取一个数据源(source)→ 数据转换→执行操作获取想要的结果,每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换)
四、流的使用
-
获得一个流的方式
- 通过集合创建
List<Integer> integerList = Arrays.asList(1,2,3,4,5,6); Stream<Integer> streamlist =integerList.stream(); //创建并行Stream Stream<Integer> streamlist1 =integerList.parallelStream(); // Stream<List<Integer>> integerList1 = Stream.of(integerList); Stream<Integer> integerList1 = Stream.of(1,2,3);
- 通过数组创建
int [] intArray = {1,2,3,4,5,6,7,8,9,12,23,34,45,56}; // Stream<int[]> intArray1 = Stream.of(intArray); IntStream streaAmrray = Arrays.stream(intArray); Stream<Integer> intArray1 = Stream.of(1,2,3,1,5);
- 3种基本数据类型
IntStream
LongStream
DoubleStream- Files.lines()
-
中间操作符
map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered
- 终端操作符
forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
五、常用操作符
- 创建大量数据流
/**
* generate产生无限个数据,参数为消费型接口;
*/
Stream.generate(()->"听说有很多个我").forEach(System.out::println);
- 创建有规律的数据
/**
* iterate()方法产生无限个数据,有两个参数,第一个为初始数据,第二个为一个Operator接口
*/
Stream.iterate(1,s->s+1).forEach(System.out::println);
- limit()
- 该方法会返回一个不超过给定长度的流
Stream.iterate(1,s->s+1).limit(20).forEach(System.out::println);
- filter()
- 该方法返回表达式判断值为true值
//返回偶数
/**
* filter()参数为断言型接口;
*/
Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 23, 34, 45, 56).stream().filter(x -> x % 2 == 0).forEach(System.out::println);
- distinct()
- 去除重复元素
Arrays.asList(1, 2, 1,2,2,2,3).stream().distinct().forEach(System.out::println);
- skip()
- 跳过前n项元素
Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().skip(6).forEach(System.out::println);
- map()
- 对流中的每个元素执行一个函数,使得元素转换成另一种类型输出,即把一种类型的Stream变为另一种类型的Stream。方法内需要一个Function接口
//将每个元素乘以2
int[] intArray = {1, 2, 3, 4, 5, 6, 7, 8, 9};
Arrays.stream(intArray).map(x->x<<2).forEach(System.out::println);
- flatMap()
- 把两个流合并起来,即扁平化为一个流.
//首先拆分字符串去掉空格变为string数组,
//然后通过flatMap将层级扁平化,装换为流对象
Stream.of("this is flatMap test").map(s->s.split(" ")).flatMap(Arrays::stream).forEach(System.out::println);
- concat()
- 一次合并两个流
Stream<Integer> a = Stream.of(1,2,3,4);
Stream<Integer> b = Stream.of(5,6,7);
Stream.concat(a,b).forEach(System.out::println);
- sorted()
- 流的排序
Arrays.asList(1, 5, 3,7,6).stream().sorted().forEach(System.out::println);
Arrays.asList(1, 5, 3,7,6).stream().sorted(x->{根据需求自定义排序规则}).forEach(System.out::println);
//根据字符串长度排序,reversed反转
Arrays.asList("sd", "ooooooo", "ssssssssss","rrrr","aaaaa").stream().sorted(
Comparator.comparing(String::length).reversed()).forEach(System.out::println);
//使用parallel时要使用forEachOrdered,不能使用forEach
Arrays.asList(4,5,2,3,6,8).stream().parallel().sorted().forEachOrdered(System.out::print);
- anyMatch()
- 是否匹配任一元素
- allMatch()
- 检查谓词是否匹配所有元素
- noneMatch()
- 是否未匹配所有元素
- findAny()
- 获取任一元素,能够从流中随便选一个元素出来,它返回一个Optional类型的元素
Optional是一种容器,可以存储一些值和null。利用这个类,可以进行null的判断,能够有效的避免NullPointerException
1、get(),可以拿到Optional中的值,没有值则抛出空指针异常
2、isPresent(),有非空的值,返回true,否则返回false
3、ifPresent(),public void ifPresent(Consumer<? super T> consumer)这个方法中需要一个Consumer接口。如果有非空的值,就执行指定的Consumer的方法来处理这个非空的值;如果为空,则啥都不做
reduce()操作返回的就是Optional
- collect()
- Stream流转变成集合
Stream<Integer> sorted = Arrays.asList(4, 5, 2, 3, 6, 8).stream().parallel().sorted();
List collect = sorted.collect(Collectors.toList());
- reduce()
- reduce的第一个参数表示初试值为0
- reduce的第二个参数为需要进行的归约操作,它接收一个拥有两个参数的Lambda表达式,reduce会把流中的元素两两输给Lambda表达式,最后将计算出累加之和
Integer reduce = Arrays.asList(4, 5, 2, 3, 6, 8).stream().reduce(0, Integer::sum);
System.out.println(reduce);
- peek()
- 对每个元素执行操作并返回一个新的 Stream
Arrays.asList("sd", "ooooooo", "ssssssssss","rrrr","aaaaa").stream().peek(s ->System.out.println(s+"AAAA")).forEach(System.out::print);
特此感谢
https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/
https://www.jianshu.com/p/cbd5713a8f26
https://blog.csdn.net/u010425776/article/details/52344425
自己敲一遍就是爽