1996年JDK1.0发布,不同版本的更新,直到Java8的发布,它所做的改变比以往的版本改动巨大,让程序编写容易,同时充分利用多核CPU的性能;
Java8新增特性:
⑴提供了一个新的API,Stream,支持许多处理数据的并行操作,使用内部迭代方法遍历集合;
⑵行为参数化,即把方法作为参数传递给另一个方法的能力;
⑶lamdba表达式,简化方法作为参数传递的写法,直接使用一种新的记法来定义参数的传入;
⑷函数方法;
⑸默认方法,使接口可以包含实现类不用提供实现的方法的签名,缺失的方法主体随接口提供;
⑹Optional<T>类,可以帮助避免出现NullPointer异常.
通过行为参数化传递代码:
理解:通过编写一个代码块,将代码块作为参数传递给另一个方法,稍后再去执行它,这样就可以理解为,这个方法的行为/功能就是基于这个代码块被参数化了.那个代码块可以理解为功能块.对于相似功能的方法可以使用这种方式来进行编写.
由于行为参数化需要根据不同的需求写重复的代码,所以为了减少冗余,所以引入了lambda,通过在参数的位置上直接实现行为主体;
lambda 可以理解为可传递的匿名函数的一种方式,没有名称,有参数列表,函数主体,返回类型,lambda的语法为: (参数1,参数2,…) -> 函数主体
之前:
Test tets = new test(){
public int test(Object o1){
return o1.getmethod();}
};
使用lambad:
(Object o1) -> ol.getmethod();
所以lambda的语法为:(parameters) -> expression或 (parameters) ->{statements;}
lambda在何处使用:lambda需要在具有函数式接口的地方使用,函数式接口就是指定义一个抽象方法的接口,ex:Runnable接口,Callable接口;
我们可以将Lambda表达式看做一个函数式接口生成的一个实例。
同时同一个Lambda可用于多个不同的函数接口;
Lambda表达式的签名就是函数式接口的抽象方法的签名,这种抽象方法叫做函数描述符,例如Runnable接口可以看做就是一个什么也不接受什么也不返回的函数的签名,例如()->void代表参数为空,且返回void的函数,
Java API中提供了几个函数式接口:
Java.util.function.Predicate<T>接口定义一个名叫test的抽象方法,它接受泛型T对象,并返回一个Boolean.
Java.util.function.Cumstomer<T>接口定义一个名叫accept的抽象方法,它接受泛型T对象,没有返回,可以对其执行某些操作
Java.util.function.Function<T,R>接口定义了一个叫做apply的方法,它接受一个泛型T的对象,并返回一个泛型R的对象,
类型检查:
Lambda的类型是从使用Lambda的上下文推断出来的,Lambda表达式需要的类型为目标类型;
ex: List<Apple> heaveThan150g = filter(inventory,(Apple a ) -> a.getWeight() > 150);(例子来自Java8实战 P49)
类型检查过程:
fileter(List<Apple>inventory ,Predicate<Apple> p)
->目标类型为Predicate<Apple> ->Predicate<Apple>接口的抽象方法为,boolean test(Apple apple)->test方法,接受一个Apple,返回一个boolean ->与函数描述符为Apple->boolean匹配.
类型推断:
Java编译器会从上下文推断出什么函数式接口来配合Lambda表达式,
方法引用:
方法引用和Lambda的方法有同样的功能,可以进行传递,可以看做是Lambda的快捷方式,如果Lambda代表的只是“直接调用这个方法”,就用名称来调用它,而不是去描述去调用它,
语法格式:
目标引用 ::方法的名称
ex: Apple :: getWeight就是引用Apple类中定义的方法getWeight;
三种方法引用:
⑴指向静态方法的方法引用,ex: Integer::parseInt
⑵指向任意类型实例方法的方法引用 ex:String::length
⑶指向现有对象的实例方法的方法引用 ex:ObjectInstance :: getValue;
读书笔记来自《Java8实战》;如有纰漏,错误,敬请指出,谢谢