java8 是java 的一个重大版本 其中较java7之前的版本更新内容多达十几项
且作为一个长期支持版本也被各大公司和开发人员所接受,从而逐渐成为主流。Spring boot 2.0 更是直接舍弃了java8之前的版本,最低支持java8. 可见java8的迷人之处,本系列将记录我学习java8的各种新特性。及帮助阅读此文章的同学尽快适应java8的脚步(截至写此文章前java11已经面世,学的不如发展的快呀!!!)。
Lambda表达式 是java8引入的一颗重量级语法糖 如果同学之前有接触过其他编程语言(Groovy、Scala、js等)一定对Lambda表达式很熟悉。而java的Lambda姗姗来迟。
以下仅以java8中新加入的 List.forEach()
进行举例说明。
List.forEach()
的用法: List<String> list= Arrays.asList("a","b","c");
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
可以看出上面的语句非常之啰嗦 我们只想对list中的值进行输出为什么还要定义匿名类,还要写方法?
List<String> list= Arrays.asList("a","b","c");
list.forEach((Object a)->{
System.out.println(a);
});
是不是比上面的简化多了。但这还不够,既然上面已经对 list
的泛型进行了定义,为什么还要我们去声明一个 Object
?
List<String> list= Arrays.asList("a","b","c");
list.forEach(a->{
System.out.println(a);
});
既如此,还不够。大括号回车党 有意见了 这句代码中只有一个输出语句为什么还要一对大括号?于是
List<String> list= Arrays.asList("a","b","c");
list.forEach(a->System.out.println(a));
注意:当大括号省略时
;
号 也必须同时省略
对比一下第一版没有Lambda时的情况是不是简化了很多?
a -> System.out.println(a)
(a,b) -> System.out.println(a+":"+b)
(a,b) -> {
if(a==b){
System.out.println(a+":"+b);
}
}
4.多参数多语句有返回值
(a,b) -> {
if(a==b){
return a;
}else{
return b;
}
}
5.单参数单语句有返回值 a -> a
FunctionalInterface函数接口(以下将直呼其中文名称 函数接口
) 严格来说不是一个新的东西,它只是一个新的定义其非严格定义如下
所有只有一个未被实现的方法的接口被统称为
函数接口
以刚才的List.forEach()
举例: 其参数为 java.util.function.Consumer
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
// default和 static 修饰的方法 是有实现的
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
其中未被实现的方法只有 accept(T t)
一个所以 java.util.function.Consumer
类是一个 函数接口
而实际上Lambda表达式实际上就是隐式实现了这个接口 并重写了其中未被实现的方法(accept(T t)
)。
我们在来看一下 List.forEach()
方法内部:
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
其实就是一个迭代循环将list中的元素当作 accept(T t)
方法的参数传入进去执行而已
一切都已经很简单了 Lambda表达式不过是编译器为了使开发变得简单,使得一个小花样而已。
@FunctionalInterface 注解并没有实际含义 对接口是不是属于函数接口并没有影响,其主要作用是用于提示开发人员和告诉编译器 请检查被@FunctionalInterface标记的接口是否只有一个未被实现的方法。
java8中新增的函数接口在 java.util.function
包下
接口 | 参数 | 返回值 |
---|---|---|
BiConsumer |
T U | void |
BiFunction |
T U | R |
BinaryOperator< T > | T T | T |
BiPredicate |
T U | boolean |
BooleanSupplier | boolean | |
Consumer< T > | T | void |
DoubleBinaryOperator | double double | double |
DoubleConsumer | double | viod |
DoubleFunction< R > | double | R |
DoublePredicate | double | boolean |
DoubleSupplier | double | |
DoubleToIntFunction | double | int |
DoubleToLongFunctio | double | long |
DoubleUnaryOperator | double | double |
Function |
T | R |
IntBinaryOperator | int | int |
IntConsumer | int | viod |
IntFunction< R > | int | R |
IntPredicate | int | boolean |
IntSupplier | int | |
IntToDoubleFunction | int | double |
IntToLongFunction | int | long |
IntUnaryOperator | int | int |
LongBinaryOperator | long long | long |
LongConsumer | long | viod |
LongFunction< R > | long | R |
LongPredicate | long | boolean |
LongSupplier | long | |
LongToDoubleFunction | long | boolean |
LongToIntFunction | long | int |
LongUnaryOperator | long | long |
ObjDoubleConsumer< T > | T double | void |
ObjIntConsumer< T > | T | int |
ObjLongConsumer< T > | T | long |
Predicate< T > | T | boolean |
Supplier< T > | T | |
ToDoubleBiFunction |
T U | double |
ToDoubleFunction< T > | T | double |
ToIntBiFunction |
T U | int |
ToIntFunction< T > | T | int |
ToLongBiFunction |
T U | long |
ToLongFunction< T > | T | long |
UnaryOperator< T > | T | T |
https://blog.csdn.net/yitian_66/article/details/81010434 ↩︎