Java JDK8—Lambda表达式/方法引用/函数式接口/默认方法/CompletableFuture

一、Lambda表达式

  1. 特点:Lambda表达式也可称作闭包,它允许把一个函数作为一个方法的参数;

  2. 语法:(parameters) -> expression 或 (parameters) -> {statements;}

    A. 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值;

    B. 可选的参数圆括号:多个参数需要定义圆括号,一个参数可以省略;

    C. 可选的大括号:主体是一个语句就不需要大括号,多个语句需要定义;

    D. 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,有大括号就需要指定返回值

  3. 变量作用域

    A. lambda表达式只能引用标记了final的外层局部变量,即不能在lambda内部修改定义在域外的局部变量,否则报编译错误;

    B. lambda表达式中不允许声明一个与局部变量同名的参数或局部变量;

    C. lambda表达式的局部变量可以不用声明为final,但是必须不可被后面的代码修改。

  

二、方法引用

  1. 特点:方法引用通过方法的名字来指定一个方法,方法引用使用一对冒号(::)

  2. 构造器引用:Class::new

  3. 静态方法引用:Class::static_method

  4. 特定类的任意方法的引用:Class::method

  5. 特定对象的方法引用:Instance::method

 

三、函数式接口

  1. 特点:函数式接口就是一个具有一个方法的普通接口,可以被隐式转换为lambda表达式,四大函数式接口都是java.util.function包下的;

  2. Function 函数式接口,有一个输入,有一个输出;

复制代码
Function<String, Integer> function = new Function<String, Integer>() {
    @Override
    public Integer apply(String o) {
       System.out.println("链式编程,流式计算,lambda表达式!” + o);
      return 1;
    }            
}  
等价于 lambda表达式中参数只有一个时,括号可以省略
Function<String, Integer> function = o -> {
  System.out.println("链式编程,流式计算,lambda表达式" + o);
  return 1;
}
复制代码

  3. Predicate 断定型接口,有一个输入参数,返回布尔值;

复制代码
Predicate<String> predicate = new Predicate<String>() {
    @Override
    public boolean test(String s) {
       System.out.println("链式编程,流式计算,lambda表达式!” + s);
      return true;
    }            
}  
等价于
Predicate<String> predicate = s -> {
  System.out.println("链式编程,流式计算,lambda表达式" + s);
  return true;
}  
复制代码

  4. Consumer 消费型接口,有一个输入参数,没有返回值;

复制代码
Consumer<String> consumer= new Consumer<String>() {
    @Override
    public void accept(String o) {
       System.out.println("链式编程,流式计算,lambda表达式!” + o);
    }            
}  
等价于
Consumer<String> consumer= o -> {
  System.out.println("链式编程,流式计算,lambda表达式" + o);
}  
复制代码

  5. Supplier 供给型接口,没有输入参数,只有返回值。

复制代码
Supplier<Integer> supplier= new Supplier<Integer>() {
    @Override
    public Integer get() {
       System.out.println("链式编程,流式计算,lambda表达式!”);
    return 1; } } 等价于 Supplier<Integer> supplier = () -> {   System.out.println("链式编程,流式计算,lambda表达式");
  return 1; }

 

四、默认方法

  1. 特点:默认方法就是借口可以有实现方法,而不需要实现类去实现方法,只需要在方法前加个default关键字。

 

五、CompletableFuture

  1. Future缺点

    A. 没有提供通知机制,任务何时结束无法准确得知;

    B. get()方法是阻塞等待异步结果,这无异于同步操作;

    C. isDone()方法是轮询判断异步结果,这很消耗CPU资源。

  2. 创建CompletableFuture对象

方法 说明
CompletableFuture<Void> runAsync(Runnable runnable) 使用ForkJoinPool.commonPool()作为它的线程池执行异步代码,无返回值
CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) 使用指定的thread pool执行异步代码,无返回值
CompletableFuture<U> supplyAsync(Supplier<U> supplier) 使用ForkJoinPool.commonPool()作为它的线程池执行异步代码,有返回值
CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) 使用指定的thread pool执行异步代码,有返回值

   3. 主动计算,获取结果

方法 说明
T join 从CompletableFuture取值,调用时会阻塞线程,运行时会抛出异常,推荐join()
V get() throws InterruptedException, ExecutionException 从CompletableFuture取值,调用时会阻塞线程
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException 与get()不同的时有超时限制
T getNow(T valueIfAbsent) 若结果已经计算完则返回结果,否则返回给定的valueIfAbsent值

  4. 超过两个以上的任务

方法 说明
CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) 会执行cfs中所有的任务
CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) 返回cfs中第一个执行完成的任务,其他任务都会被终结

 

可参考:https://blog.csdn.net/u012129558/article/details/78962759

    https://www.jianshu.com/p/6bac52527ca4

posted @ 2020-02-22 20:42  如幻行云  阅读(1085)  评论(0编辑  收藏  举报