java中sam接口,具有非SAM接口的lambdas的Java习惯用法

In Java, interfaces with a single abstract method (i.e., SAM types or functional interfaces) can be elegantly implemented with lambda instead of an anonymous class:

// SAM ActionListener with anonymous implementation

button.addActionListener(

new ActionListener(){

public void actionPerformed(Event e){

System.out.println("button via anon!");

}

}

);

can be replaced with:

// SAM ActionListener with lambda implementation

button.addActionListener(

e -> System.out.println("button via lambda!")

);

But for interfaces with multiple abstract methods, lambda cannot be directly applied. For example, java.awt.event.WindowListener has seven methods. But often a chunk a code is only interested in defining one of these seven methods.

To implement the behavior with an anonymous class override, we can:

// non-SAM with adapter implementation with override

window.addWindowListener(

new WindowAdapter() {

@Override

public void windowOpened(Event e){

System.out.println("WindowAdapter opened via override!");

}

}

);

but is there a more elegant way with lambdas?

@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!");

}

}

Note: @maythesource.com asked a similar, but broader question: "What would someone do with a MouseListener if they wanted to implement multiple methods within the anonymous class?" The most upvoted and accepted answer is to use an anonymous implementation. My question is about an elegant lambda solution for non-SAM types. Therefore, this question is not a duplicate of Java 8 Lambda Expressions - what about multiple methods in nested class.

解决方案

The most elegant way I have found is to use an anonymous bridge:

// SAM bridge with lambda implementation

window.addWindowListener(

WindowBridge.windowOpened(

b -> System.out.println("opening via lambda!")

)

);

which, like the SAM type scenario, is cleaner than the anonymous adapter:

// non-SAM with adapter implementation with override

window.addWindowListener(

new WindowAdapter() {

@Override

public void windowOpened(Event e){

System.out.println("WindowAdapter opened via override!");

}

}

);

but it does require a slightly awkward bridge with a static factory:

import java.util.function.Consumer;

public interface WindowBridge {

// SAM for this method

public abstract class WindowOpened extends WindowAdapter {

public abstract void windowOpened(Event e);

}

// factory bridge

public static WindowOpened windowOpened(Consumer c) {

return new WindowOpened() {

public void windowOpened(Event e){

c.accept(e);

}

};

}

// SAM for this method

public abstract class WindowClosing extends WindowAdapter {

public abstract void windowClosing(Event e);

}

// factory bridge

public static WindowClosing windowClosing(Consumer c) {

return new WindowClosing() {

public void windowClosing(Event e){

c.accept(e);

}

};

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值