扫描关注公众号查看更多内容
近期在研读《Java 8 in Action》中文版(中文《java8实战》),感觉受益良多,故想向大家分享这本书籍,并写下自己的对于其中的理解。
前言
Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。
lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。
如我们所知,我们可以使用Lambda表达式来简化代码,让我们的代码看起来更加的简洁整齐。
在Java8之前,我们需要使用行为参数化,获得一个实现接口的类的实例时,我们总会用匿名内部类,如下
new Predicate<String>(){
boolean test(String s){
xxxx
}
}
但是在Java8新特性广泛使用后,我们就会用Lambda表达式来表达同一段代码,如下
(String s) -> {xxxx }
这就很直观的简化了很多有没有!!
ps:当然其中有很多语法需要注意,例如在方法内只有返回一个对象时,我们省去花括号及return关键字 return
(String s) -> s.length()
当我们想要加上return时,那么我们就需要花括号拉
(String s -> {return s.length();})
但是,又有人会说了,我们每次想要行为参数化的时候都需要创建一个接口那也太麻烦了把
那么,Java8中也贴心的提供了供我们使用的函数式接口。
当我们需要一个实现有返回boolean值的接口时,我们可以使用
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
当我们需要实现无返回值的接口时,我们可以使用
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
或者当我们需要有传参和返参时,那么我们就可以使用
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
等等等等…
可能又有人想要说了,泛型只提供引用类型的使用,那我们需要基本类型的传参怎么办呢,难道只能耗费性能包装一下吗
java8当然不会这么不贴心拉,请往下看
真的太多了把!!请根据具体的场景选择使用噢
需要注意的时,这些接口中的方法绝大部分都未声明异常信息,所以如果在方法中需要检查异常时,就只能在代码中显示捕捉异常了(try catch)
你以为现在的Lambda表达式已经是最简洁了嘛?当然不是
接下来介绍Lambda表达式的方法引用,可以依照一些简单的方子
方法引用主要有三类:
(1)指向静态方法的方法引用(例如Integer的parseInt方法,写作Integer: :parseInt )。
(2)指向任意类型实例方法的方法引用(例如string的length方法,写作string: :length )。
(3)指向现有对象的实例方法的方法引用(假设你有一个局部变量expensiveTransaction用于存放Transact ion类型的对象,它支持实例方法getvalue,那么你就可以写expensiveTransaction: :getValue )。
请注意,方法引用中还有一种叫构造函数引用,在这我就不举例了,感兴趣的小伙伴可以自行百度学习
小结
1.Lambda表达式可以理解为- -种匿名函数:它没有名称,但有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常的列表。
2.Lambda表达式让你可以简洁地传递代码。
3.函数式接口就是仅仅声明了一个抽象方法的接口。
4.只有在接受函数式接口的地方才可以使用I ambda表达式。
5.Lambda表达式允许你直接内联,为函数式接口的抽象方法提供实现,并且将整个表达式作为函数式接口的一个实例。
6.为了避免装箱操作,对predicate 和Function<T, R>等通用函数式接口的原始类型特化: IntPredicate、 IntToLongFunction等。