gpt4 book ai didi

具有非 SAM 接口(interface)的 lambda 的 Java 习惯用法

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:54:10 25 4
gpt4 key购买 nike

在 Java 中,可以使用 lambda 而不是匿名类来优雅地实现具有单个抽象方法的接口(interface)(即 SAM 类型或功能接口(interface)):

    // SAM ActionListener with anonymous implementation
button.addActionListener(
new ActionListener(){
public void actionPerformed(Event e){
System.out.println("button via anon!");
}
}
);

可以替换为:

    // SAM ActionListener with lambda implementation
button.addActionListener(
e -> System.out.println("button via lambda!")
);

但是对于有多个抽象方法的接口(interface),不能直接应用lambda。例如,java.awt.event.WindowListener 有七个方法。但通常一段代码只对定义这七种方法中的一种感兴趣。

要使用匿名类重写来实现行为,我们可以:

    // non-SAM with adapter implementation with override
window.addWindowListener(
new WindowAdapter() {
@Override
public void windowOpened(Event e){
System.out.println("WindowAdapter opened via override!");
}
}
);

但是有没有更优雅的 lambda 方式?

@FunctionalInterface
public interface ActionListener {
void actionPerformed(Event e);
}

public interface WindowListener {
void windowOpened(Event e);

void windowClosing(Event e);
}

public class WindowAdapter implements WindowListener {

public void windowOpened(Event e){
System.out.println("windowOpened in adapter!");
}

public void windowClosing(Event e){
System.out.println("windowClosing in adapter!");
}
}

注意:@maythesource.com 问了一个类似但更广泛的问题:“如果有人想在匿名类中实现多个方法,他们会用 MouseListener 做什么?”最受赞誉和接受的答案是使用匿名实现。我的问题是关于非 SAM 类型的优雅 lambda 解决方案。因此,此问题不是 Java 8 Lambda Expressions - what about multiple methods in nested class 的重复 .


最佳答案

Brian Goetz' answer to the other question ,他建议使用静态工厂方法。在这种情况下,它有点乏味,因为 WindowListener 定义了 七个 处理程序方法,因此您需要定义七个静态工厂方法。不过,这并没有那么糟糕,因为已经有一个 WindowAdapter 类提供了所有方法的空实现。 (如果没有,您必须定义自己的等价物。)这是我的做法:

class WLFactory {
public static WindowListener windowOpened(Consumer<WindowEvent> c) {
return new WindowAdapter() {
@Override public void windowOpened(WindowEvent e) { c.accept(e); }
};
}

public static WindowListener windowClosing(Consumer<WindowEvent> c) {
return new WindowAdapter() {
@Override public void windowClosing(WindowEvent e) { c.accept(e); }
};
}

// ...
}

(The other 253 cases are analogous.)

每个工厂方法都会创建一个 WindowAdapter 的子类,该子类会覆盖相应的方法以调用传入的 lambda 表达式。不需要额外的适配器或桥接类。

它将按如下方式使用:

window.addWindowListener(WLFactory.windowOpened(we -> System.out.println("opened")));

关于具有非 SAM 接口(interface)的 lambda 的 Java 习惯用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25299653/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com