2015-10-31 67 views
2

我正在尋求用lambda替換對單獨的獨立靜態短語函數的需求。例如我想替換這樣的東西...JDK庫是否提供lambda'invoker'實用類?

class Foo { 
    private static final Set<String> keywords = keywords(); 

    private static Set<String> keywords() { 
     HashSet<String> s = new HashSet<>(); 
     s.add("AND"); 
     s.add("NOT"); 
     s.add("OR"); 
     return Collections.unmodifiableSet(s); 
    } 
} 

有些東西調用了在類加載時定義的lambda。請注意,這不是我的目標。

目前,我用靜態方法創建了一個簡單的Initializer類,該方法接受Supplier,調用它並返回值。

Initializer

public class Initializer { 
    public static <T> T init(Supplier<T> initializer) { 
     return initializer.get(); 
    }  
} 

然後在另一個類:

import static com.whatever.Initializer.init; 

class Foo { 
    private static final Set<String> keywords = init(() -> { 
     HashSet<String> s = new HashSet<>(); 
     s.add("AND"); 
     s.add("NOT"); 
     s.add("OR"); 
     return Collections.unmodifiableSet(s); 
    }); 
} 

有什麼存在於標準Java庫已經如此,我並不需要提供我自己的Initializer類,還是有一些方法來簡單地定義,然後執行一個lambda就地?

+1

你不需要一個方法來初始化關鍵字。你的lambda版本究竟是什麼? – zeroflagL

+1

爲什麼你在這裏需要lambda?看起來你只需要一個靜態初始化塊('static {}')並在那裏調用你的inits? – Zhedar

+0

相關:[如何使用lambda初始化映射?](http://stackoverflow.com/questions/32868665/how-to-initialize-a-map-using-a-lambda) –

回答

2

您可以只投拉姆達並稱之爲:

private static final Set<String> KEYWORDS = ((Supplier<Set<String>>)() -> { 
    Set<String> result = new HashSet<>(); 
    ... 
    return Collections.unmodifiableSet(result); 
}).get(); 

或者你可以使用現有的快捷方式:

private static final Set<String> KEYWORDS = 
    Collections.unmodifiableSet(new HashSet<>(Arrays.asList("AND", "NOT", "OR"))); 

但是你的原代碼,調用一個方法,是非常具有可讀性。我不會改變它。

+2

對於這個特殊情況,我喜歡Guava集合:'KEYWORDS = ImmutableSet.of(「AND」,「NOT」,「OR」)' –

+0

我仍然沒有從普通的靜態初始值設定中獲得這種lambda使用的好處。事實上,它與問題的原始方法甚至沒有區別,因爲代碼仍然在一個靜態方法內,現在是一個綜合方法。只有被調用的方式在這裏有更多的開銷。 – Holger

+0

@Holger我同意100%。我只是想表明這是可能的。但正如我的答案所說,我發現原始代碼更具可讀性,並且不會改變它。 –

1

正如@zeroflagL所提到的,你不需要在這個地方使用lambdas。您可以通過使用初始化一行keywords

Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("AND", "NOT", "OR"))); 

但是這不是那麼漂亮。否則,使用static塊有什麼問題?它是爲這樣的事情創造的。

但是,如果你不想使用它,我認爲沒有標準的方法。您必須使用您的初始化程序。

2

我會寫只是特殊的工具方法,做全產業鏈:

public class Sets { 
    public static <T> Set<T> of(T... elements) { 
     return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(elements))); 
    } 
} 

而且使用它在必要時:如果你碰巧使用番石榴

private static final Set<String> KEYWORDS = Sets.of("AND", "NOT", "OR"); 

,目前已經有bunch of such methods。希望這種功能將出現在Java-9中。有JEP 269這將允許寫Set.of("AND", "NOT", "OR")

+0

雖然這對集合很有用,但它不適用於其他類型的初始化。 – Bill

+1

@Bill,如果「其他類型的初始化」(不管它是什麼)不能在單個表達式中執行,可能應該重構它。考慮創建新的構造函數,工廠方法或實現構建器模式。我認爲解決這個問題要比爲每個案例解決這個問題要好得多,而不是創建醜陋的普通解決方案。 –

相關問題