jdk1.8新特性之lambda表达式
Posted 不想下火车的人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdk1.8新特性之lambda表达式相关的知识,希望对你有一定的参考价值。
lambda表达式其实就是指一个匿名函数,应用最广泛的就是匿名内部类的简化。在jdk1.8之前,我们定义一个匿名内部类可能需要写一大坨代码,现在有了lambda之后,可以写的很简洁了。但不是说lambda只能用来简化匿名内部类,从lambda的实际作用和表现上来看,它就是一个变量指代了一个代码块。而能够使用lambda表达式的一个前提要求是,该变量必须实现某个函数式接口。啥是函数式接口?参考jdk1.8新特性之函数式接口。看一个匿名内部类的例子:
FutureTask<String> coverTask = new FutureTask<String>(new Callable() { public String call() { return PortalBookCoverCacheService.getInstance().getBookCover(bookItem, PropertiesConfig.getProperty("cdnUrl")); } });
上面在实例化FutureTask对象的时候,使用了Callable接口实例的匿名内部类,实际上FutureTask构造器里就是一个Callable的实例:
Callable callable = new Callable() { public String call() { return PortalBookCoverCacheService.getInstance().getBookCover(bookItem, PropertiesConfig.getProperty("cdnUrl")); } };
如果我们使用lambda表达式,上面的callable变量实际上就是
Callable callable = () -> { return PortalBookCoverCacheService.getInstance().getBookCover(bookItem, PropertiesConfig.getProperty("cdnUrl")); } ;
callable变量指代的就是一段代码块,把这个变量放入FutureTask的构造器里,匿名内部类可以简化为:
FutureTask<String> coverTask = new FutureTask<String>(() -> { return PortalBookCoverCacheService.getInstance() .getBookCover(bookItem, PropertiesConfig.getProperty("cdnUrl")); });
为啥能这么简化呢?因为它符合lambda表达式规范,即Callable是一个函数式接口:
/** <a href="http://www.cpupk.com/decompiler">Eclipse Class Decompiler</a> plugin, Copyright (c) 2017 Chen Chao. */ /* * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */ package java.util.concurrent; /** * A task that returns a result and may throw an exception. * Implementors define a single method with no arguments called * {@code call}. * * <p>The {@code Callable} interface is similar to {@link * java.lang.Runnable}, in that both are designed for classes whose * instances are potentially executed by another thread. A * {@code Runnable}, however, does not return a result and cannot * throw a checked exception. * * <p>The {@link Executors} class contains utility methods to * convert from other common forms to {@code Callable} classes. * * @see Executor * @since 1.5 * @author Doug Lea * @param <V> the result type of method {@code call} */ @FunctionalInterface public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception; }
所以可以我们通过lambda表达式省略了接口类型、方法名和方法参数(因为这里call方法根本就不需要参数),->符号的左边是参数列表(如果有参数的话),右边是方法体。lambda其实是通过编译器的强大而赋予的能力,编译器通过自动匹配接口类型、智能识别参数列表,可以像考古学家根据蛛丝马迹恢复物品的原貌的一样,还原出匿名内部类的本来面目。
以上是关于jdk1.8新特性之lambda表达式的主要内容,如果未能解决你的问题,请参考以下文章