2014-04-11 115 views
57

具體來說,我有TabPane,我想知道是否有具有特定ID的元素。如何使用lambda表達式檢查元素是否存在?

所以,我想在Java中使用lambda表達式來做到這一點:

boolean idExists = false; 
String idToCheck = "someId"; 

for (Tab t : tabPane.getTabs()){ 
    if(t.getId().equals(idToCheck)) { 
     idExists = true; 
    } 
} 

回答

138

嘗試使用Lambda表達式的anyMatch。這是更好的方法。

boolean idExists = tabPane.getTabs().stream() 
      .anyMatch(t -> t.getId().equals(idToCheck)); 
22

雖然接受的答案是正確的,我將添加一個更優雅版(在我看來):

boolean idExists = tabPane.getTabs().stream() 
    .map(Tab::getId) 
    .anyMatch(idToCheck::equals); 

不要忽視使用Stream#map()允許申請前扁平化的數據結構Predicate

+2

這裏有什麼更好?我只看到一次手術。對不起,我是這個lamba的新手。 – TecHunter

+2

@TecHunter它更加明確。想象一下你第一次閱讀這段代碼,或者過一段時間後再讀這段代碼。有幾個優點:首先,我們立即表明我們對該選項卡沒有真正的興趣,但有一些映射。其次,通過使用方法引用(這是唯一可能的,因爲我們將初始lambda分成兩步),我們顯示代碼中沒有隱藏的意外。第三,通過使用方法引用,我們不創建一個新的謂詞,但實際上只是重用了'equals'。雖然,理所當然,這裏的例子非常簡單,但我希望你明白我的意思。 –

+0

@MalteHartwig謝謝!是的,我得到了你的3分,但我用「地圖」詢問了這個扁平化,它做了另一個處理步驟否?我會嘗試比較2種方法:) – TecHunter

0

上面的答案要求你malloc一個新的流對象。

public <T> 
boolean containsByLambda(Collection<? extends T> c, Predicate<? super T> p) { 

    for (final T z : c) { 
     if (p.test(z)) { 
      return true; 
     } 
    } 
    return false; 
} 

public boolean containsTabById(TabPane tabPane, String id) { 
    return containsByLambda(tabPane.getTabs(), z -> z.getId().equals(id)); 
} 
... 
if (containsTabById(tabPane, idToCheck))) { 
    ... 
}