zoukankan      html  css  js  c++  java
  • 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其实是通过编译器的强大而赋予的能力,编译器通过自动匹配接口类型、智能识别参数列表,可以像考古学家根据蛛丝马迹恢复物品的原貌的一样,还原出匿名内部类的本来面目。

      

      

  • 相关阅读:
    多步操作产生错误,请检查每一步的状态值
    MediaPlayer 播放百度歌曲
    MusicPlayer
    wpf slider 控件模板
    c# 静态构造函数
    好吧,学了久c#,params都不知道怎么用,记录下
    C# 使用各种API
    WPF转义字符
    WPF 执行完一段动画后再关闭窗口
    WPF xml的绑定
  • 原文地址:https://www.cnblogs.com/wuxun1997/p/9099654.html
Copyright © 2011-2022 走看看