你大概没意识到Java对函数式编程的重视水平,看看Java 8插手函数式编程扩充几多成果就清楚了。Java 8之所以费这么大工夫引入函数式编程,原因有二:
parallel()
要领。这一节我们进修stream,也就是Java函数式编程的主角。对付Java 7来说stream完全是个生疏对象,stream并不是某种数据布局,它只是数据源的一种视图。这里的数据源可以是一个数组,Java容器或I/O channel等。正因如此要获得一个stream凡是不会手动建设,而是挪用对应的东西要领,好比:
Collection.stream()
可能Collection.parallelStream()
要领Arrays.stream(T[] array)
要领常见的stream接口担任干系如图:
图中4种stream接口担任自BaseStream
,个中IntStream, LongStream, DoubleStream
对应三种根基范例(int, long, double
,留意不是包装范例),Stream
对应所有剩余范例的stream视图。为差异数据范例配置差异stream接口,可以1.提高机能,2.增加特定接口函数。
你大概会奇怪为什么不把IntStream
等设计成Stream
的子接口?究竟这接口中的要领名大部门是一样的。谜底是这些要领的名字固然沟通,可是返回范例差异,假如设计成父子接口干系,这些要领将不能共存,因为Java不答允只有返回范例差异的要领重载。
固然大部门环境下stream是容器挪用Collection.stream()
要领获得的,但stream和collections有以下差异:
对stream的操纵分为为两类,中间操纵(intermediate operations)和竣事操纵(terminal operations),二者特点是:
假如你熟悉Apache Spark RDD,对stream的这个特点应该不生疏。
下表汇总了Stream
接口的部门常见要领:
操纵范例 | 接口要领 |
---|---|
中间操纵 | concat() distinct() filter() flatMap() limit() map() peek() skip() sorted() parallel() sequential() unordered() |
竣事操纵 | allMatch() anyMatch() collect() count() findAny() findFirst() forEach() forEachOrdered() max() min() noneMatch() reduce() toArray() |
区分中间操纵和竣事操纵最简朴的要领,就是看要领的返回值,返回值为stream的多半是中间操纵,不然是竣事操纵。
stream要领利用
stream跟函数接口干系很是细密,没有函数接口stream就无法事情。回首一下:函数接口是指内部只有一个抽象要领的接口。凡是函数接口呈现的处所都可以利用Lambda表达式,所以不必影象函数接口的名字。
forEach()
我们对forEach()
要领并不生疏,在Collection
中我们已经见过。要领签名为void forEach(Consumer<? super E> action)
,浸染是对容器中的每个元素执行action
指定的行动,劳务派遣管理系统,也就是对元素举办遍历。
// 利用Stream.forEach()迭代 Stream<String> stream = Stream.of("I", "love", "you", "too"); stream.forEach(str -> System.out.println(str));
由于forEach()
是竣事要领,上述代码会当即执行,输出所有字符串。
filter()