Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java8 Lambdas与匿名类_Java_Lambda_Java 8_Anonymous Class - Fatal编程技术网

Java8 Lambdas与匿名类

Java8 Lambdas与匿名类,java,lambda,java-8,anonymous-class,Java,Lambda,Java 8,Anonymous Class,由于Java8最近发布,其全新的lambda表达式看起来非常酷,我想知道这是否意味着我们已经习惯的匿名类的消亡 我对此进行了一些研究,发现了一些很酷的例子,说明Lambda表达式将如何系统地替换这些类,例如集合的sort方法,该方法用于获取Comparator的匿名实例来执行排序: Collections.sort(personList, new Comparator<Person>(){ public int compare(Person p1, Person p2){

由于Java8最近发布,其全新的lambda表达式看起来非常酷,我想知道这是否意味着我们已经习惯的匿名类的消亡

我对此进行了一些研究,发现了一些很酷的例子,说明Lambda表达式将如何系统地替换这些类,例如集合的sort方法,该方法用于获取Comparator的匿名实例来执行排序:

Collections.sort(personList, new Comparator<Person>(){
  public int compare(Person p1, Person p2){
    return p1.firstName.compareTo(p2.firstName);
  }
});
而且看起来非常简洁。所以我的问题是,有没有理由继续在Java8中使用这些类而不是Lambdas

编辑


同样的问题,但相反,使用Lambdas而不是匿名类有什么好处,因为Lambdas只能用于单个方法接口,这个新功能只是一个仅在少数情况下使用的快捷方式,还是真的有用?

Lambdas虽然是一个很好的功能,但只适用于SAM类型。也就是说,只与一个抽象方法进行接口。只要接口包含多个抽象方法,它就会失败。这就是匿名类有用的地方

所以,不,我们不能忽略匿名类。仅供参考,您的
sort()
方法可以更加简化,方法是跳过
p1
p2
的类型声明:

Collections.sort(personList, (p1, p2) -> p1.firstName.compareTo(p2.firstName));
您也可以在这里使用方法引用。您可以在
Person
类中添加
compareByFirstName()
方法,并使用:

Collections.sort(personList, Person::compareByFirstName);
或者,为
firstName
添加一个getter,直接从方法中获取
比较器

匿名内部类(AIC)可用于创建抽象类或具体类的子类。AIC还可以提供接口的具体实现,包括添加状态(字段)。AIC的实例可以在其方法体中使用
this
来引用,因此可以对其调用其他方法,其状态可以随时间变化,等等。这些都不适用于lambda

我猜AIC的大多数用途是提供单个函数的无状态实现,因此可以用lambda表达式代替,但还有其他用途不能使用lambda。AIC在这里停留

更新


AICs和lambda表达式之间的另一个区别是,AICs引入了一个新的作用域。也就是说,名称是从AIC的超类和接口解析的,并且可以隐藏在词汇封闭环境中出现的名称。对于Lambda,所有名称都是按词汇进行解析的。

Java8中的Lambda是为函数式编程引入的。您可以避免使用样板代码。我在lambda上看到了这篇有趣的文章


建议对简单逻辑使用lambda函数。如果使用Lambda实现复杂逻辑,则在出现问题时调试代码时会产生开销。

匿名类的Lambda性能

启动应用程序时,必须加载并验证每个类文件

匿名类由编译器作为给定类或接口的新子类型进行处理,因此将为每个类或接口生成一个新的类文件

lambda在字节码生成方面不同,它们更高效,使用JDK7附带的invokedynamic指令

对于lambda,此指令用于将字节码中的lambda表达式延迟到运行时。(仅第一次调用指令)

结果,Lambda表达式将成为一个静态方法(在运行时创建)。
(stateles和statefull案例有一点不同,它们是通过生成的方法参数解决的)

有以下区别:

1)语法

与匿名内部类(AIC)相比,Lambda表达式看起来整洁

2)范围

匿名内部类是一个类,这意味着它在内部类中定义了变量的作用域

然而,lambda表达式不是它自己的作用域,而是封闭作用域的一部分。

在使用匿名内部类和lambda表达式时,类似规则适用于super关键字。对于匿名内部类,该关键字表示本地范围,super关键字表示匿名类的超类。而对于lambda表达式,该关键字引用封闭类型的对象,super将引用封闭类的super类

//AIC
    public static void main(String[] args) {
        final int cnt = 0; 
        Runnable r = new Runnable() {
            @Override
            public void run() {
                int cnt = 5;    
                System.out.println("in run" + cnt);
            }
        };

        Thread t = new Thread(r);
        t.start();
    }

//Lambda
    public static void main(String[] args) {
        final int cnt = 0; 
        Runnable r = ()->{
            int cnt = 5; //compilation error
            System.out.println("in run"+cnt);};
        Thread t = new Thread(r);
        t.start();
    }
3)性能

在运行时,匿名内部类需要类加载、内存分配、对象初始化和非静态方法调用,而lambda表达式是纯编译时活动,在运行时不会产生额外成本。所以和匿名内部类相比,lambda表达式的性能更好**

**我确实意识到这一点并不完全正确。详情请参阅以下问题

  • lambda语法不需要编写java可以推断的明显代码
  • 通过使用
    invoke dynamic
    lambda在编译时不会转换回匿名类(Java不需要创建对象,只需要关心方法的签名,就可以绑定到方法而不创建对象)
  • lambda更强调我们想做什么,而不是我们必须做什么才能做到

匿名类将继续存在,因为lambda适用于具有单个抽象方法的函数,但对于所有其他情况,匿名内部类都是您的救星。

当然,对于所有提供有副作用的方法的匿名类。仅为您提供信息,您还可以将比较器构造为:
comparator.comparating(Person::getFirstName)
,如果
getFirstName()
是返回
firstName+----------------------------------+----------------------------------------------------------+---------------------------------------------+
|                                  |                                       Lambdas            |              Anonymous classes              |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Definition                       | An anonymous method that can be created without belonging| An inner class without a name.              |
|                                  | to any class                                             |                                             |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Scope of variables of main class | Available                                                | Not available                               |
| (this and super keywords also)   |                                                          |                                             |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Lines of codes                   | Reduced the lines of code. It’s a short form of          | Have more lines of code compared to lambdas |
|                                  | anonymous class.                                         |                                             |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Criteria for creating            | Needs to be Functional Interface, ie interface with      | Can use interfaces(including Functional     |
|                                  | only one abstract method. Example : Runnable Interface   | interfaces) and abstract classes to create. |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Example:                         | Runnable r = ()->{System.out.println("Hello World");};   | Runnable r = new Runnable() {               |
|                                  |                                                          |         @Override                           |
|                                  |                                                          |         public void run() {                 |
|                                  |                                                          |          System.out.println("Hello World"); |
|                                  |                                                          |                                        }    |
|                                  |                                                          |     };                                      |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
public static void main(String[] args) {
    Runnable r = new Runnable() {
        @Override
        public void run() {
            System.out.println("in run");
        }
    };

    Thread t = new Thread(r);
    t.start(); 
}

//syntax of lambda expression 
public static void main(String[] args) {
    Runnable r = ()->{System.out.println("in run");};
    Thread t = new Thread(r);
    t.start();
}
//AIC
    public static void main(String[] args) {
        final int cnt = 0; 
        Runnable r = new Runnable() {
            @Override
            public void run() {
                int cnt = 5;    
                System.out.println("in run" + cnt);
            }
        };

        Thread t = new Thread(r);
        t.start();
    }

//Lambda
    public static void main(String[] args) {
        final int cnt = 0; 
        Runnable r = ()->{
            int cnt = 5; //compilation error
            System.out.println("in run"+cnt);};
        Thread t = new Thread(r);
        t.start();
    }
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
|                                  |                                       Lambdas            |              Anonymous classes              |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Definition                       | An anonymous method that can be created without belonging| An inner class without a name.              |
|                                  | to any class                                             |                                             |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Scope of variables of main class | Available                                                | Not available                               |
| (this and super keywords also)   |                                                          |                                             |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Lines of codes                   | Reduced the lines of code. It’s a short form of          | Have more lines of code compared to lambdas |
|                                  | anonymous class.                                         |                                             |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Criteria for creating            | Needs to be Functional Interface, ie interface with      | Can use interfaces(including Functional     |
|                                  | only one abstract method. Example : Runnable Interface   | interfaces) and abstract classes to create. |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+
| Example:                         | Runnable r = ()->{System.out.println("Hello World");};   | Runnable r = new Runnable() {               |
|                                  |                                                          |         @Override                           |
|                                  |                                                          |         public void run() {                 |
|                                  |                                                          |          System.out.println("Hello World"); |
|                                  |                                                          |                                        }    |
|                                  |                                                          |     };                                      |
+----------------------------------+----------------------------------------------------------+---------------------------------------------+