2014-09-24 36 views
2

我只是嘗試了很少的java-8函數式編程,我對lamda表達式的行爲幾乎沒有懷疑。我試圖用簡單的命令模式來解釋下面的問題。Java-8 lambda表達式與函數接口的行爲

public interface Editor { 
    public void open(); 
    public void close(); 
// public void save(); 

} 

編輯器實現

public class MyEditor implements Editor { 

    @Override 
    public void open() { 
     System.out.println("...opening"); 

    } 

    @Override 
    public void close() { 
     System.out.println("...closing"); 
    } 

} 

接口行動

// this is actually a @FunctionalInterface 
public interface Action { 
    public void perform(); 

} 

可操作的項目。

public class Open implements Action { 

    private final Editor editor; 

    public Open(Editor editor) { 
     this.editor = editor; 
    } 

    @Override 
    public void perform() { 
     editor.open(); 
    } 

// Similarly Close implements Action... 

...

宏來運行所有的動作。

public class Macro { 

    private final List<Action> actions; 

    public Macro() { 
     actions = new ArrayList<>(); 
    } 

    public void record(Action action) { 
     actions.add(action); 
    } 

    public void run() { 
     actions.forEach(Action::perform); 
    } 
} 

現在運行宏是interesing部分的地方。

public class RunMacro { 
    public static void main(String[] args) { 
     Editor editor= new MyEditor(); 
     Macro macro = new Macro(); 
     macro.record(() -> editor.open());// Line 4 
     macro.record(new Close(editor)); // Line 5 
     macro.run(); 
    } 
} 

我的問題是,4號線的運行,如何Java的理解,創造一個instanceof打開,並將其添加到宏中。簡而言之,lamdba表達式的行爲與第5行的行爲相同。整個模式通過lambda表達式變得更簡單但是使用OOPS進行函數式編程是否使開發處於非常抽象的級別或不太冗長?

禮貌的問題:O'Reilly Media公司:Java的8個Lamdbas

可以在任何一個請澄清這一點?

回答

7

Java如何理解創建一個instanceof Open並將其添加到宏?

您應該閱讀java教程的Lambda Expressions中的Target Typing部分。 當你寫道:

macro.record(() -> editor.open()); 

你不是在創造開放類的一個實例。您沒有創建生成的匿名類的實例。

請參閱Translation strategy部分Translation of Lambda Expressions

代替生成字節代碼創建實現lambda表達式(如,要求內部類的構造函數)的對象,我們描述了一種配方用於構建拉姆達,和代表實際施工的語言運行時。該配方編碼在invokedynamic指令的靜態和動態參數列表中。


你也可以採取優勢的Java 8 method references的,並再次簡化代碼:

Editor editor= new MyEditor(); 
    Macro macro = new Macro(); 
    macro.record(editor::open); 
    macro.record(editor::close); 
    macro.run(); 

你最後可能會刪除Action接口,並使用Runnable之一。這允許例如使用java.util.concurrent的所有東西,如Executor,新的Java承諾:CompletableFuture ...

+1

是啊!這是我正在尋找的,謝謝(: – chaosguru 2014-09-24 08:07:30

+0

謝謝(:這是更多的聲明方式 – chaosguru 2014-09-24 08:17:21

+1

)對,我真的很喜歡方法引用和java 8引入了很多偉大的東西,沒有失去它的簡單性更大的java版本 – gontard 2014-09-24 08:20:10

0

Lambda構造是一個非常可讀的替代品,它是Java語言的長期部分構造:匿名類。事實上,關於你的意圖,你可以將lambda表達式看作是一個匿名類,儘管技術上有很大的不同。

只需添加第三個變種作爲你的record方法:

macro.record(new Action() { 
    @Override public void perform() { editor.open(); } 
}); 

這裏要傳遞一個匿名類的一個實例(的Action一個子類)的記錄方法。這是lambda表達式是相同的:

macro.record(() -> editor.open()); 

對於這兩個變種,你甚至不需要Open類。嘗試一下,並從源代碼中刪除它。

+0

好吧,我明白了,謝謝你的闡述。 – chaosguru 2014-09-24 08:05:38