137

Specifically, I have TabPane, and I would like to know if there is element with specific ID in it.

So, I would like to do this with lambda expression in Java:

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

for (Tab t : tabPane.getTabs()){
    if(t.getId().equals(idToCheck)) {
        idExists = true;
    }
}
1
  • I would be writing with simple way and clean with List.contains method. Example: return tabPane.getTabs().contains(idToCheck); Commented Jan 4, 2021 at 11:46

3 Answers 3

316

Try to use anyMatch of Lambda Expression. It is much better approach.

 boolean idExists = tabPane.getTabs().stream()
            .anyMatch(t -> t.getId().equals(idToCheck));
Sign up to request clarification or add additional context in comments.

2 Comments

Also worth noting: if you want to negate the check use noneMatch instead of anyMatch.
Call requires API level 24
55

While the accepted answer is correct, I'll add a more elegant version (in my opinion):

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

Don't neglect using Stream#map() which allows to flatten the data structure before applying the Predicate.

6 Comments

what is better here? I only see one more operation. Sorry I'm new to this lamba thing.
@TecHunter it is more explicit. Imagine you read this code the first time, or again after a while. There are several advantages: First, we immediately show that we are not actually interested in the tab, but some mapping of it. Second, by using method references (which is only possible because we break the initial lambda into two steps) we show that there are no surprises hidden in the code. Third, by using method references, we do not create a new Predicate, but really just re-use equals. Though, granted, the example here is very simple, but I hope you get what I mean.
@MalteHartwig thanks! yeah I get your 3 points but I was asking about the flattening with map, it does another processing step no? I will try to compare the 2 methods :)
@MalteHartwig tested in a 10kk ArrayList with a simple object trying to find the last element. gives a 2ms difference 131ms against 133ms for your. on a 1kk array list yours if faster by 2ms (55ms to 53ms). So we can say that yours is better :)
@TecHunter getters are super-cheap. Always prefer code clarity over saving extra 2 milliseconds (even though, I doubt the results are accurate, it may fluctuate on every run). Besides, remember that intermediate operations on streams (such as map) are lazy by nature. That means that getId method is not applied to each element of the collection. It's evaluated lazily until anyMatch returns true.
|
3

The above answers require you to malloc a new stream object.

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))) {
   ...
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.