1. Lambda表达式和函数式接口
Java 8中,Function,Consumer,Predicate,Supplier:
Function<T, R>: R apply(T t); 接受一个入参T,输出一个返回值R;
Supplier<T> : T get(); 无入参,输出一个类型为T的返回值;
Consumer<T>:void accept(T t); 输入一个入参T,无返回;
Predicate<T>: boolean test(T t); 输入一个入参T,返回一个boolean值 ;
2. 接口的默认方法和静态方法
默认方法使用default关键字
3. 方法引用
- 构造方法引用(Class::new)
- 静态方法引用(Class:static_method),只支持一个参数
- 类实例方法引用(Class::method),方法没有参数
- 引用特殊类(instance::method),只支持一个参数
4. 重复注释
5. 更好的类型推断
6. 注解的扩展
7. Stream
1)Intermediate:
map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered
2)Terminal:
forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
3)Short-circuiting:
anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit
- map/flatMap:把 input Stream 的每一个元素,映射成 output Stream 的另外一个元素。map是一对一映射,flatMap是一对多映射;
- filter: 对原始 Stream 进行某项测试,通过测试的元素被留下来生成一个新 Stream
- forEach : 在 Stream 的每一个元素上执行该表达式
- peek : 每个元素执行操作并返回一个新的 Stream
- findFirst:返回 Stream 的第一个元素,或者空,重点的是它的返回值类型:Optional,作为一个容器,它可能含有某值,或者不包含。使用它的目的是尽可能避免 NullPointerException
- reduce : 把 Stream 元素组合起来,供一个起始值(种子),然后依照运算规则(BinaryOperator),和前面 Stream 的第一个、第二个、第 n 个元素组合。
- limit/skip : limit 返回 Stream 的前面 n 个元素;skip 则是扔掉前 n 个元素
- sorted : 排序
- min/max/distinct : min 和 max 的功能也可以通过对 Stream 元素先排序,再 findFirst 来实现,但前者的性能会更好,为 O(n),而 sorted 的成本是 O(n log n)。
- distinct 去重
- Match : 匹配,allMatch、anyMatch、noneMatch
- Stream.generate:控制流的生成
- Stream.iterate:iterate 跟 reduce 操作很像,接受一个种子值,和一个
UnaryOperator(例如 f)。然后种子值成为 Stream 的第一个元素,f(seed) 为第二个,f(f(seed)) 第三个。与 Stream.generate 相仿,在 iterate 时候管道必须有 limit 这样的操作来限制 Stream 大小。 - Collectors :辅助进行各类有用的 reduction 操作,例如转变输出为 Collection,把 Stream 元素进行归组。
- groupingBy/partitioningBy:
8、Stream 的特性可以归纳为:
-
不是数据结构
它没有内部存储,它只是用操作管道从 source(数据结构、数组、generator function、IO channel)抓取数据。
它也绝不修改自己所封装的底层数据结构的数据。例如 Stream 的 filter 操作会产生一个不包含被过滤元素的新 Stream,而不是从 source 删除那些元素。
所有 Stream 的操作必须以 lambda 表达式为参数 -
不支持索引访问
你可以请求第一个元素,但无法请求第二个,第三个,或最后一个。不过请参阅下一项。
很容易生成数组或者 List -
惰性化
很多 Stream 操作是向后延迟的,一直到它弄清楚了最后需要多少数据才会开始。
Intermediate 操作永远是惰性化的。 -
并行能力
当一个 Stream 是并行化的,就不需要再写多线程代码,所有对它的操作会自动并行进行的。 -
可以是无限的
集合有固定大小,Stream 则不必。limit(n) 和 findFirst() 这类的 short-circuiting 操作可以对无限的 Stream 进行运算并很快完成。