Question

Does any common Java library provide a method to find an element in a finite collection and ensure that there was exactly one match?

The method could, for example, return null if nothing was found and throw an exception if multiple elements were found.

Currently I use my own Implementation (see below), but I'd rather not pollute business code with such utility methods (even if extracted in a separate utility package).

I also don't want the overhead of iterating over collection more than once, or an overhead of filtering collection and looking at the length of the result.

P.S. my current solution (which works, but is to be replaced with a library method):

public static <T> T getSingleMatch(Iterable<T> lookIn, com.google.common.base.Predicate<? super T> predicate) {
    T foundItem = null;
    for (T item : lookIn) {
        if (predicate.apply(item)) {
            if (foundItem != null) 
                throw new RuntimeException("multiple matches"); // alternatively: `return null;` 
            else 
                foundItem = item;
        }
    }
    // alternatively: `if (foundItem == null) throw ...`
    return foundItem;
}
Was it helpful?

Solution

One option is to separate out the two ideas into two methods, so that each method does one thing - then combine the calls

  • One method to lazily filter, returning a sequence of matching results
  • One method to return an item from a sequence, requiring it to be the only item

Guava has both of those:

So for example:

String match = Iterables.getOnlyElement(Iterables.filter(source, predicate));

OTHER TIPS

int index = collection.indexOf(item);
if (index != -1 && index == collection.lastIndexOf(item)) {
    // one and only one
}

If index != -1 it means no such item. If the next if statement doesn't evaluate to true it means that there are at least 2 items. You can restructure it to throw exceptions, return null or return the index or item. I trust you know how to do this based on your question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top