As far as I know, there are no built-in functions directly related to this task. Therefore, since you cannot avoid creating utility methods (if you want to reduce code duplication), it is worth considering what kind of useful method can be useful in other scenarios.
eg. if this was my project, I knew that methods for applying a partial function are almost always used, for example:
public static <T,U,R> Function<U,R> bind(BiFunction<T,U,R> f, T t) { return u -> f.apply(t, u); }
Using this existing method, the solution might look like this:
static <T> boolean contains(List<T> list, T item, Comparator<? super T> comparator) { return list.stream().map(bind(comparator::compare, item)) .anyMatch(Predicate.isEqual(0)); }
But this is not necessarily the best solution.
Another approach would be a method to convert a Comparator
to BiPredicate
equality and a utility method to partially apply a BiPredicate
:
public static <T> BiPredicate<T,T> match(Comparator<T> f) { return (a,b)->f.compare(a, b)==0; } public static <T,U> Predicate<U> bind(BiPredicate<T,U> f, T t) { return u -> f.test(t, u); }
Then the contains
method becomes as simple as
static <T> boolean contains(List<T> list, T item, Comparator<? super T> comparator) { return list.stream().anyMatch(bind(match(comparator), item)); }
But this is only a simplification if the utility methods can be used elsewhere in your project. On the other hand, they are so general that similar methods can be added as default
methods to functional interfaces in a subsequent release of Java. In this case, your code using these utility methods is ready to upgrade to this newer version.