如何使用Lambda表达式检查元素是否存在?


118

具体来说,我有TabPane,我想知道其中是否包含具有特定ID的元素。

因此,我想使用Java中的lambda表达式来做到这一点:

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

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

Answers:


273

尝试使用anyMatchLambda表达式。这是更好的方法。

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

11
另外值得注意的是:如果您想取消使用支票,请使用noneMatch代替anyMatch
Blacklight

通话要求API级别24
FabioLux

50

尽管所接受的答案是正确的,但我将添加一个更优雅的版本(我认为):

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

不要忽略使用Stream#map(),它允许在应用之前将数据结构弄平Predicate


3
这里有什么更好的?我只看到另一项操作。抱歉,我是这个兰巴舞的新手。
TecHunter

2
@TecHunter更明确。假设您是第一次或一段时间后再次阅读此代码。有几个优点:首先,我们立即表明我们实际上对选项卡不感兴趣,但对其有一些映射。其次,通过使用方法引用(这是唯一可能的,因为我们将初始lambda分为两个步骤)表明,代码中没有隐藏的惊喜。第三,通过使用方法引用,我们不会创建新的谓词,而实际上只是重复使用equals。尽管理所当然,这里的示例非常简单,但是我希望您能理解我的意思。
马尔特·哈特维格

@MalteHartwig谢谢!是的,我得到了3分,但我在询问关于展平的问题map,这是否还需要其他处理步骤?我将尝试比较两种方法:)
TecHunter

1
@MalteHartwig在10kk ArrayList中测试了一个简单的对象,试图找到最后一个元素。给出131ms与133ms的2ms差异。在1kk阵列上列出您的速度是否快2ms(55ms至53ms)。所以我们可以说您的更好:)
TecHunter

2
@TecHunter吸气剂非常便宜。总是比节省额外的2毫秒更喜欢代码的清晰度(尽管我怀疑结果是否准确,它可能会在每次运行时有所波动)。此外,请记住,流(例如map)上的中间操作本质上是惰性的。这意味着该getId方法不适用于集合的每个元素。延迟评估它,直到anyMatch返回true
jFrenetic

3

上述答案要求您分配一个新的流对象。

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))) {
   ...
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.