2015-11-13 34 views
1

的返回值我有一個接口,它是獲取參數和lambda

public static interface MyClass{ 
    public boolean doSomething(boolean a, boolean b); 
} 

然後我實例變量

MyClass a = (boolean x, boolean y) -> x && y; 

現在我的問題是,如果我想要得到的參數x和y和返回值,我會怎麼做呢?我想得到參數的原因是因爲我想序列化,以便我能夠與他們做一個ObjectOutputStream.writeObject()

不知道我的問題是否完全合理。我沒有太多的lambda工作,所以任何形式的指導將不勝感激。

添加:確定,以便MyClass a在另一個類中實例化,我們將其稱爲ParentClass。所以現在我有

MyClass a = (x, y) -> x && y; 
    ParentClass b = new ParentClass(); 
    b.setMyClass(a); 

現在,在我的工作中的主類,我獲得通過ParentClass b。所以我拿它並做 MyClass c = b.getMyClass; 如果我理解正確的話,可以參考(x, y) -> x && y;。現在的問題是,我如何獲取參數的值和返回值,以便序列化它。此外MyClass的不會永遠是(x,y) -> x && y,它可以是任何東西即

MyClass a = (x, y) -> x || y; 
MyClass a = (x, y) -> x^y; 
MyClass a = (x, y) -> true; 

我不允許修改MyClass的父類或。這就是爲什麼我試圖讓參數通過和返回值,以便我可以序列化這些併發送它們。

+1

你傳遞的X和Y,怎麼可能你不知道他們的價值? – m0skit0

+0

我得到的是變量a。我沒有直接訪問x和y,也沒有直接訪問返回值。 – user2989280

+0

你怎麼無法訪問? – redFIVE

回答

2

在Java中,lambda語法簡單地說就是一種描述方法行爲而不給它起一個名字的方法。

例如(Type1 arg1, Type2 arg2, ...) -> <expression> 定義一個函數看起來像這樣:

public TypeOfExpression anonymousMethod(Type1 arg1, Type2 arg2, ...) { 
    ... 
    return <expression>; 
} 

一下就Java Tutorials有關lambda表達式的更多信息。

事實上lambda表達式(boolean x, boolean y) -> x && y(給定類型MyClass當你定義它)是什麼,但語法糖以下:

new MyClass() { 
    public boolean doSomething(boolean x, boolean y) { 
     return x && y; 
    } 
} 

希望,讓一些清晰到什麼lambda表達式在Java中表示。

從技術上講,您給出的接口定義定義了'function type'。在Java中,任何只有一個方法的接口被稱爲「功能性」,並且可以用作接口中與單一方法相同類型的lambda表達式的類型,而不是接口。

這一決定是可能作出,因爲如果一個接口只有一個方法,來指定它是該方法中,其可以是遠更簡明地寫在拉姆達符號,如以上所表明的行爲所有需要的。

因此,lambda表達式不過是您的接口的一個實例 - 特別是,它沒有字段,但定義了一個方法行爲。我想你是在假設它封裝了一對輸入和它們的輸出結果。如果這是你所需要的,那麼你可能會尋找更類似於內置操作的配對類型(例如在這種情況下爲&&)。

編輯:關於可串行性。

很明顯,您需要序列化MyClass類型的未知函數。如果MyClass擴展爲Serializable,則應該能夠正確轉換並序列化。如果您不能控制MyClass,所以無法確保這一點,下面的特別觀察可能會有所幫助。

如果MyClass中的方法確實是此處顯示的類型(boolean, boolean) -> boolean,則有足夠多的情況下可以考慮手動序列化。

的「可能」(總)A -> B類型的函數,對於有限尺寸的類型和AB數爲|B|^|A|(的B大小的A功率大小)。這是因爲,對可能的函數進行計數,對於A類型的每個輸入,函數可能會輸出|B|個可能的輸出。

而且,對類型(A, B)的尺寸是|A| * |B|

在我們的案例中,我們有(boolean, boolean) -> boolean。但boolean只有2號!所以(boolean, boolean)的大小是4,而(boolean, boolean) -> boolean的大小是2^4 = 16。

我們如何計算出我們手中的這16個函數中的哪一個?簡單列舉可能的投入(只有4個可以做)。然後,我們可以記錄四個輸出變量是這樣的(其中a將是我們未知的功能。)

boolean ttout = a(true, true); 
boolean tfout = a(true, false); 
boolean ftout = a(false, true); 
boolean ffout = a(false, false); 

然後我們就可以歡快序列化這四個值。 :)

而且,如果我們反序列化,並獲得四個值(ttouttfout ...),我們可以重建功能是這樣的:

a = (boolean x, boolean y) -> { 
    if (x) { 
     if (y) return ttout; 
     else return tfout; 
    } else { 
     if (y) return ftout; 
     else return ffout; 
    } 
} 
+0

好的,我開始更多地理解語法(已經在網上進行了大量的閱讀),並且您的轉換也很有意義。但我最初的問題仍然存在。我有'MyClass a =(x,y) - >(某個返回值)''。這是在另一個類中實例化的,我只給了變量a。我如何序列化該變量? – user2989280

+0

如果序列化接口/ lambda表達式是你所需要的,它看起來好像人們已經建議好東西了。但是'MyClass'擴展'Serializable'將是必要的,但是:如果您期待着一個未知的MyClass實例,那麼您不能假設它不是可序列化的。 – Oly

+0

如果你不控制'MyClass'的定義(所以不能確保它是可序列化的),我發現的一件事情是,如果實際上所有實例都在(原始)布爾輸入上操作,實際上只有需要考慮四個輸入 - 您可以手動序列化布爾值上的任何可能的二進制操作,只需四位! (一個用於輸入的結果(true,true),一個用於(true,false).....) – Oly

1

如果你想a本身是可序列化的,你可以寫a = (MyClass & Serializable) (boolean x, boolean y) -> x && y

沒有距離的a定義xy,雖然:當實際調用a那些只存在。

3

我懷疑你誤解了lambda表達式的工作原理。您的問題意味着您期望創建您的a對象,然後對其進行序列化,並在此過程中以某種方式記錄xy的值。我的理解正確嗎?

如果是這樣,那麼這基本上不是lambda表達式的工作原理。它們不是一般意義上的包含狀態的對象。相反,把它們想象成一些可執行代碼,你可以隨時傳遞這些代碼,只要你願意就可以應用到一組值中(我懷疑我會因爲過於簡單化的解釋而在評論中受到抨擊!)。

您可以序列化lambda表達式,但在這種情況下,您將序列化由lambda表示的操作,而不是在任何給定的調用中傳遞給它的值。

如果您希望MyClass接口的實現可串行化,那麼它需要擴展Serializable。它看起來應該如下:

@FunctionalInterface 
public interface MyClass extends Serializable { 
    boolean doSomething(boolean a, boolean b); 
} 

如果您不能修改MyClass,那麼你仍然能投射出MyClass對象Serializable

Serializable a = (Serializable & MyClass)(a, b) -> a || b; 

或者,如果你正在使用從ParentClass值:

Serializable a = (Serializable)b.getMyClass(); 

然後,您應該可以序列化a

只要記住,當你反序列化,你需要退回到MyClass,以便您可以使用它。它看起來像這樣:

MyClass b = (Serializable & MyClass)objectInStream.readObject(); 
b.doSomething(true, false); 
+0

好吧,這是有道理的...我怎樣才能去序列化一個lambda?我幾乎沒有任何lambda經驗,更不用說理解如何序列化它。 – user2989280

+0

http://stackoverflow.com/questions/22807912/how-to-serialize-a-lambda – sprinter

+0

我看過那篇文章,但不明白如何在我的函數中實現它。我做'MyClass a =(MyClass&Serializable)b.getMyClass();'但是當我將它寫入輸出流時,我得到的Lambda不能轉換爲java.io.Serializable – user2989280