java8新特性从入门到应用 第一章 Lambda表达式及FunctionalInterface函数接口

java8 是java 的一个重大版本 其中较java7之前的版本更新内容多达十几项
且作为一个长期支持版本也被各大公司和开发人员所接受,从而逐渐成为主流。Spring boot 2.0 更是直接舍弃了java8之前的版本,最低支持java8. 可见java8的迷人之处,本系列将记录我学习java8的各种新特性。及帮助阅读此文章的同学尽快适应java8的脚步(截至写此文章前java11已经面世,学的不如发展的快呀!!!)。

Lambda表达式

Lambda表达式 是java8引入的一颗重量级语法糖 如果同学之前有接触过其他编程语言(Groovy、Scala、js等)一定对Lambda表达式很熟悉。而java的Lambda姗姗来迟。
以下仅以java8中新加入的 List.forEach() 进行举例说明。

  • 先看一下无Lambda时 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中的值进行输出为什么还要定义匿名类,还要写方法?

  • 于是拯救万千程序猿的Lambda来了,上面的可简写为:
		List<String> list= Arrays.asList("a","b","c");
		list.forEach((Object a)->{
            System.out.println(a);
        });

是不是比上面的简化多了。但这还不够,既然上面已经对 list 的泛型进行了定义,为什么还要我们去声明一个 Object

  • java8给我们带来了更好的类型推断,于是可以接着简化:
        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时的情况是不是简化了很多?

lambda表达式的特征: 1
  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
常用 Lambda写法:
  1. 单参数单语句无返回值 a -> System.out.println(a)
  2. 多参数单语句无返回值 (a,b) -> System.out.println(a+":"+b)
  3. 多参数多语句无返回值
(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函数接口

FunctionalInterface函数接口(以下将直呼其中文名称 函数接口) 严格来说不是一个新的东西,它只是一个新的定义其非严格定义如下

所有只有一个未被实现的方法的接口被统称为 函数接口

以刚才的List.forEach() 举例: 其参数为 java.util.function.Consumer<T>

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<T> 类是一个 函数接口
而实际上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 注解并没有实际含义 对接口是不是属于函数接口并没有影响,其主要作用是用于提示开发人员和告诉编译器 请检查被@FunctionalInterface标记的接口是否只有一个未被实现的方法。

java 8中新增的函数接口

java8中新增的函数接口在 java.util.function 包下

接口参数返回值
BiConsumer<T,U>T Uvoid
BiFunction<T,U,R>T UR
BinaryOperator< T >T TT
BiPredicate<T,U>T Uboolean
BooleanSupplierboolean
Consumer< T >Tvoid
DoubleBinaryOperatordouble doubledouble
DoubleConsumerdoubleviod
DoubleFunction< R >doubleR
DoublePredicatedoubleboolean
DoubleSupplierdouble
DoubleToIntFunctiondoubleint
DoubleToLongFunctiodoublelong
DoubleUnaryOperatordoubledouble
Function<T,R>TR
IntBinaryOperatorintint
IntConsumerintviod
IntFunction< R >intR
IntPredicateintboolean
IntSupplierint
IntToDoubleFunctionintdouble
IntToLongFunctionintlong
IntUnaryOperatorintint
LongBinaryOperatorlong longlong
LongConsumerlongviod
LongFunction< R >longR
LongPredicatelongboolean
LongSupplierlong
LongToDoubleFunctionlongboolean
LongToIntFunctionlongint
LongUnaryOperatorlonglong
ObjDoubleConsumer< T >T doublevoid
ObjIntConsumer< T >Tint
ObjLongConsumer< T >Tlong
Predicate< T >Tboolean
Supplier< T >T
ToDoubleBiFunction<T,U>T Udouble
ToDoubleFunction< T >Tdouble
ToIntBiFunction<T,U>T Uint
ToIntFunction< T >Tint
ToLongBiFunction<T,U>T Ulong
ToLongFunction< T >Tlong
UnaryOperator< T >TT

  1. https://blog.csdn.net/yitian_66/article/details/81010434 ↩︎

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值