zoukankan      html  css  js  c++  java
  • Lambda表达式

    Lambda表达式,是Java8引入的一个重要新语法,它是一种紧凑的传递代码的方式。

    Lambda表达式之前

    首先,需要先回顾一下接口、匿名内部类和代码传递。以File类的listFiles(FilenameFilter filter)方法为例:

        public File[] listFiles(FilenameFilter filter) {
            ...
        }

    其中,FilenameFilter是一个接口,这种接口有个特点,就是只有一个方法:

    @FunctionalInterface
    public interface FilenameFilter {
        boolean accept(File dir, String name);
    }

    这个接口只有一个accept()方法,实际上仅从编程上说,FilenameFilter就是为了传递accept方法体代码的。

    再看listFiles方法,它需要的其实不是一个FilenameFilter对象,而是它包含的accept(File dir, String name)方法。或者说,listFiles更希望直接接受一段方法代码作为参数,但是语法不支持方法作为参数,所以只能传递一个接口。

    完整写法如下:

        /*自定义一个FilenameFilter类*/
        private class MyFilter implements FilenameFilter {
    
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".txt");
            }
        }
    
        public void test() {
            MyFilter mFilter = new MyFilter();  //创建接口实例
            File file = new File("/usr/bin");
            file.listFiles(mFilter);  //接口实例作为参数传入方法
        }

    另一种更简洁的方法是使用匿名内部类,这也是Lambda表达式之前最简洁的写法了:

        public void test() {
            File file = new File("/usr/bin");
            //使用匿名内部类
            file.listFiles(new FilenameFilter(){
    
                @Override
                public boolean accept(File dir, String name) {
                    return name.endsWith(".txt");
                }
            });
        }

    Lambda表达式

    引入Lambda表达式之后,这种写法可以继续简化:

        public void test() {
            File file = new File("/usr/bin");
            //使用Lambda表达式
            file.listFiles((File dir, String name) -> {
                return name.endsWith(".txt");
            });
        }

    Lambda表达式由->分割成两部分,前面是方法的参数,后面{}内是方法的代码。因为这种接口只有一个方法,所以Java可以自行推断出参数类型,所以Lambda表达式的参数类型可以省略:

        public void test() {
            File file = new File("/usr/bin");
            //使用Lambda表达式,省略参数类型
            file.listFiles((dir, name) -> {
                return name.endsWith(".txt");
            });
        }

    上面的写法已经是Lambda表达式的一般写法了,但对于两种特殊情况,还有更加简洁的写法:

    (1)当方法体代码只有一条语句的时候,括号{}和return语句也可以省略:

        public void test() {
            File file = new File("/usr/bin");
            //使用Lambda表达式,省略括号{}和return语句
            file.listFiles((dir, name) -> name.endsWith(".txt"));
        }

    (2)当方法只有一个参数的时候,括号()也可以省略(这里假设accept方法只有一个参数name):

        public void test() {
            File file = new File("/usr/bin");
            //使用Lambda表达式,省略括号()
            file.listFiles(name -> name.endsWith(".txt"));
        }

    总结

      对比代码可以看出,Lambda表达式要比匿名内部类在语法上简化很多。那Lambda表达式是不是仅仅是语法糖,其内部依然是匿名内部类呢?答案是否定的,Java会为每个匿名内部类生成一个类,但Lambda表达式不会。Lambda表达式的效率更高,它实际上是Java8引入的新概念:函数式接口。回看最上面的FilenameFilter接口定义,发现它有一个新的注解:@FunctionalInterface。拥有此注解的接口是函数式接口,只能定义一个方法,定义多个方法时会出现编译错误;即使没有此注解,只要接口只定义了一个方法,这个接口也是函数式接口。

  • 相关阅读:
    【MySQL】【2】数字排序问题
    【MySQL】【1】表中存在重复记录,删除保留其中一条
    poj 1811 Prim test
    Yours 的博客开张啦!
    P1044
    P1103
    hustwinter1-B
    hustwinterC
    hustwinter1-A
    hdu 2138 How many prime numbers
  • 原文地址:https://www.cnblogs.com/not2/p/11177423.html
Copyright © 2011-2022 走看看