Java 8 Lambda表达式具有仅具有一个方法的抽象类 [英] Java 8 lambda expression with an abstract class having only one method

查看:577
本文介绍了Java 8 Lambda表达式具有仅具有一个方法的抽象类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Java 8中的lambda表达式.有人可以向我解释如何将lambda表达式与只有一种方法的抽象类一起使用(如果可能的话)?

I'm learning lambda expressions in Java 8. Can somebody explain to me how to use lambda expression with an abstract class having only one method (if it's possible)?

例如,这是抽象类:

public abstract class ClassA {

    public abstract void action();

}

我还有另一个类,在其构造函数中使用ClassA的实例:

And I have another class that take's in its constructor an instance of ClassA:

public ClassB {
   public ClassB(String text, ClassA a){
      //Do stuff
    }
}

所以我想知道如何写这样的东西:

So I was wondering how to write something like this:

ClassB b = new ClassB("Example", new ClassA(() -> System.out.println("Hello")));

显然,该语句不起作用,但是有没有办法在这里使用lambda表达式?如果有,我在做什么错了?

Obviously that statement doesn't work, but is there a way to use a lambda expression here or not? If there is, what am I doing wrong?

推荐答案

否,您无法实现,因为ClassA必须是功能接口.功能接口是仅包含一个抽象方法的接口.除抽象方法外,它可能包含零个或多个默认方法和/或静态方法.由于功能接口仅包含一个抽象方法,因此在使用lambda表达式实现该方法时,可以省略该方法的名称.例如,考虑以下接口:

No, you cannot achieve this because ClassA must be a functional interface. A functional interface is an interface that contains exactly one abstract method. It may contain zero or more default methods and/or static methods in addition to the abstract method. Because a functional interface contains exactly one abstract method, you can omit the name of that method when you implement it using a lambda expression. For example, consider the following interface:

interface Predicate<T> {
    boolean test(T t);
}

此接口的目的是提供一种对T类的对象进行操作并返回boolean的方法.您可能有一个采用类实例的方法,该实例实现了如下定义的接口:

The purpose of this interface is to provide a method that operates on an object of class T and return a boolean. You could have a method that takes an instance of class that implements this interface defined like this:

public void printImportantData(ArrayList<Data> dataList, Predicate<Data> p) {
    for (Data d : dataList) {
        if (p.test(d)) {
            System.out.println(d);
        }
    }
}

其中Data类可能很简单:

public class Data {
    public int value;
}

现在,您可以按以下方式调用上述方法:

Now, you can call the above method as follows:

 printImportantData(al, (Data d) -> { return d.value > 1; }); 

请注意,该方法在此处没有名称.这是可能的,因为接口只有一个抽象方法,因此编译器可以找出名称.可以缩短为:

Notice the method does not have a name here. This is possible because the interface has only one abstract method so the compiler can figure out the name. This can be shortened to:

printImportantData(al, (Data d) -> d.value > 1);

请注意,这里没有大括号,也没有return关键字.这是可能的,因为该方法返回一个布尔值,而表达式d.value > 1也返回一个布尔值.因此,编译器能够确定该表达式的值将从方法中返回.可以将其进一步缩短为:

Notice that here are no curly brackets and no return keyword. This is possible because the method returns a boolean and the expression d.value > 1 also returns a boolean. The compiler is therefore able to figure out that the value of this expression is to be returned from the method. This can be shortened even more to:

printImportantData(al, d -> d.value > 1);

请注意,没有d的类型声明!编译器可以找出所需的所有信息,因为该接口只有一个抽象方法,而该方法只有一个参数.因此,您无需在代码中编写所有这些内容.
使用可以有效完成相同操作的内部类将上述方法与旧的Java 7样式进行比较:

Notice that there is no type declaration of d! The compiler can figure out all information it needs because the interface has only one abstract method and that method has only one parameter. So you don't need to write all those things in your code.
Compare the above approach to the old Java 7 style using an inner class that does effectively the same thing:

printImportantData(al, new Predicate<Data>() {
    public boolean test(Data d) {
        return d.value > 1;
    }
});

这篇关于Java 8 Lambda表达式具有仅具有一个方法的抽象类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆