如何使用Lambda?

List greenApples = filter(inventory,(Apple a) -> "green".equals(a.getColor()));

到底在哪里可以使用Lambda呢?可以在函数式接口上使用Lambda表达式。

在上面的代码中,可以把Lambda表达式作为第二个参数传给filter方法,因为它这里需要Predicate,而这是一个函数式接口。

函数式接口

Predicate仅仅定义了一个抽象方法:

public interface Predicate{
    boolean test(T t);
}

函数式接口就是只定义一个抽象方法的接口。如下所示:

public interface Runnable{
    void run();
}
public interface Callable{
    V call();
}
public interface PrivilegedAction{
    V run();
}

判断以下是否是函数式接口?

//符合函数式接口定义,属于函数式接口
public interface Adder{
    int add(int a,int b);
}
//不是函数式接口,因为它定义了两个叫作add的抽象方法
public interface SmartAdder extends Adder{
    int add(double a,double b);
}
//不是函数式接口,因为它没有声明抽象方法
public interface Nothing{
    
}

函数式接口可以干什么呢?Lambda表达式允许你直接以内联的形式为函数式接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例(具体说来,是函数式接口一个具体实现的实例)

用匿名内部类也可以完成同样的事情,只不过比较笨拙:需要提供一个实现,然后再直接将它实例化。

下面的代码是有效的,因为Runnable接口是一个只定义了一个抽象方法run的函数式接口:

Runnable r1 = () -> System.out.println("Hello World");
Runnable r2 = new Runnable(){
    public void run(){
        System.out.println("Hello World");
    }
}
public static void process(Runnable r){
    r.run();
}
process(r1);
process(r2);
//直接传递Lambda打印
process(() -> System.out.println("Hello World"));

函数描述符

函数式接口的抽象方法的签名基本上就是Lambda表达式的签名。我们将这种抽象方法叫作函数描述符

() -> void 代表了参数列表为空,且返回void的函数。这正是Runnable接口所代表的。

(Apple,Apple) -> int 代表接受两个Apple作为参数且返回int的函数。

判断如下使用Lambda场景是否正确?

public void execute(Runnable r){
    r.run();
}
//签名相同()->void,所以该场景下Lambda是有效的
execute(() -> {});
//该场景正确,因为Lambda签名与方法返回一致 () -> String
public Callable fetch(){
    return () -> "Tricky example  ;-";
}
//错误,签名不一致实际返回 (Apple)->int,而定义的是(Apple)->boolean
Predicate p = (Apple a) -> a.getWeight();

你可能感兴趣的:(Java8,java,开发语言)