It seems to be a very common thing to have to tell whether some list or set contains at least one object matching a given condition, yet my prior searching and reading have never found a satisfactory best practice or design pattern to speak of. In the situations I am thinking of, merely using "contains" is not sufficient, as the test we want to perform is not strictly based on the equals method of the class in question.
Some things I have seen:
// for-each with break
private boolean doFoosHaveGoodQuality(List<Foo> candidates) {
boolean foundIt = false;
for (Foo item: candidates) {
if (<< item passes some test >>) {
fountIt = true;
break;
}
}
return foundIt;
}
// while-do with index counter
private boolean doFoosHaveGoodQuality(List<Foo> candidates) {
boolean foundIt = false;
int index = 0;
while(!fountIt && index < candidates.size() - 1) {
Foo item = candidates.get(index++);
if (<< item passes some test >>) {
fountIt = true;
}
}
return foundIt;
}
Both of these get the job done and quit as soon as a success is found, possibly saving some time if we are lucky enough to have the desired item early in the list. However, both require looping the entire list in order to get a false result
Another technique I've seen in some circumstances is that at the same time the original List<Foo>
is generated (i.e. retrieved from database) to then simultaneously generate a Map<FooKey, Foo>
. In this technique, FooKey
is an additional (often inner) class
holding only those attributes of a Foo
that form the "desired quality" and overrides equals and hash code methods based on that. When you need to determine if there exists a desired Foo, you make a new FooKey()
instance with exactly that you want, then call hasKey()
on the map. Extra effort up front, but quick and easy at the moment you need it.
I can't put a finger on it. Each idea works, yet each feels just a little hacky and inefficient.