介绍

流,一个抽象的概念,当我听到流这个词时,第一想到的画面是流动的水,如何在程序中理解它,我的理解是:流,动态的,具有方向性,而不是静态的,对于Java8之前的输入流,输出流的理解,流的方向取决于数据与内存;其二,流是数据的一种状态,流的本质是数据,输入流,输出流中包含着想要传输的数据。

流这个概念在Java8之后,它成为Java的API,Java8实战的定义是”从支持数据处理操作的源生成的元素序列“,我对这句话的理解是:流是数据序列和处理过程,和数据类型这个概念的理解相似,数据类型就是表示数据值的范围以及在这组值上的操作。Java8提供了Stream接口,用来将数据转化为流来进行相应的操作。

操作

Java8中将流操作分为两大类:中间操作,终端操作。中间操作是不执行任何处理,它的作用就是将流连接起来,中间操作有:filter,map,limit,sorted,distinct。终端操作就是进行流的全部处理,并生成结果,同时在处理结束后关闭流,终端操作有:forEach,count,collect。

我的理解分为三部分,流的生成,流的处理,流的结束。

流的生成:

⑴由值构建⑵由数组创建⑶文件生成⑷函数生成无限流(需要进行截断)

	Stream<String> stream = Stream.of("java","python","C");
	int [] num = {1,2,3,4,5};
	IntStream intstream = Arrays.stream(num);
	Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset());
	Stream.iterate(0, n->n+1).limit(10).forEach(System.out::println);
	Stream.generate(Math::random).limit(10).forEach(System.out::println);
        //集合转换为流
        List<Students> stus = Arrays.asList(new Students("ld", 999, "china"),
				new Students("lx", 1023, "china"),
				new Students("lds", 1293, "china"));
		
	stus.stream();

流的处理

流的处理包括流的连接,和结果的生成。(结果的生成在流的终端操作中,在这里我将流的连接和流的结果归并于流的处理,Java8中将流的结果和结束归并于终端操作)

流的处理有:

filter:用于过滤元素

limit:用于获取特定长度的流

skip:用于返回一个扔掉了前n个元素的流

map:用于将函数应用于流中的每个元素,返回一个新的流

flatMap:用于将各个生成的流扁平化为单个流

anyMatch():用于至少匹配一个元素

allMatch():用于全部匹配元素

noneMatch():用于确保流中没有任何元素匹配

findFirst():用于查找流的第一个元素

reduce:用于将函数作用于流中的元素反复结合起来,得到一个新值。将函数作用于流的前几个元素,然后将结果计算到流中,然后再运行函数作用于新的流中,以此类推,得到最终的结果。

注意:由于Stream接口没有定义有关原始数据类型的一些方法,例如sum,所以在需要求和的时候,需要将Stream转化为原始类型特化流接口,如IntStream,DoubleStream,LongStream分别将流中的元素特化为int,long.double。如果想要将特化流转回非特化流,则使用boxed方法。

stus.stream()
	.filter(student -> student.getId()>1000)
	.map(Students::getName)
	.limit(2)
	.skip(1)
	.forEach(System.out::println);

流的结束

在Java8之前,流的结束需要使用close()方法,但在Java8中的流的结束即执行终端操作,在执行终端操作后,会得到一个值,然后流就结束。

收集器的介绍

Stream的collect是一个终端操作,可以接受参数,将流中的元素累积成一个汇总结果,传递给collect方法的参数是Collector接口的一个实现。收集器即指的是Collector的实例,实例可以从数据中根据特定的需求收集指定的数据。一般Collector会对元素应用一个转换函数,并将结果累积到一个数据结构中,从而产生最终输出。Collectors类提供了很多静态工厂方法,可以方便的创建常见的收集器的实例。

常见的收集器:

stus.stream().collect(Collectors.summingInt(Students::getId));
stus.stream().map(Students::getName).collect(Collectors.joining(", "));
stus.stream().collect(Collectors.reducing(0,Students::getId,(i,j)->i+j));
//分组
stus.stream().collect(Collectors.groupingBy(Students::getName));
stus.stream().collect(Collectors.groupingBy(Students::getName,Collectors.counting()));
//分区
Map<Boolean,List<Students>> partionedMenu = stus.stream().collect(Collectors.partitioningBy(Students::isadult));
List<Students> adultpeople = partionedMenu.get(true);

 

 

参考《Java8实践》