Reputation: 1565
I'm currently facing a code readability issue. The problem is the following:
Have three objects
// initialization skipped, all of three could be null as result of their initalization
Object obj1;
Object obj2;
Object obj3;
I want to create two booleans from them as follows:
// all are null
boolean bool1 = (obj1 == null && obj2 == null && obj3 == null);
// any of them is null
boolean bool2 = (obj1 == null || obj2 == null || obj3 == null);
I know guava provides built-in predicates like isNull
and notNull
.
Is there a way to implement a custom predicate that fulfills those two booleans? (assuming that .apply(..)
function would take 3 parameters then)
Upvotes: 2
Views: 2455
Reputation: 3529
Easy to implement in vanilla Java 8:
/**
* Check that <b>at least one</b> of the provided objects is not null
*/
@SafeVarargs
public static <T>
boolean anyNotNull(T... objs)
{
return anySatisfy(Objects::nonNull, objs);
}
/**
* Check that <b>at least one</b> of the provided objects satisfies predicate
*/
@SafeVarargs
public static <T>
boolean anySatisfy(Predicate<T> predicate, T... objs)
{
return Arrays.stream(objs).anyMatch(predicate);
}
/**
* Check that <b>all</b> of the provided objects satisfies predicate
*/
@SafeVarargs
public static <T>
boolean allSatisfy(Predicate<T> predicate, T... objs)
{
return Arrays.stream(objs).allMatch(predicate);
}
//... other methods are left as an exercise for the reader
(See what and why @SaveVarargs)
Usage:
// all are null
final boolean allNulls1 = !anyNotNull(obj1, obj2, obj3);
final boolean allNulls2 = allSatisfy(Objects::isNull, obj1, obj2, obj3);
// any of them is null
final boolean hasNull = anySatisfy(Objects::isNull, obj1, obj2, obj3);
P.S. General note for novice programmers. Guava is great library, but if you want it only because of some small and easy bit (like this one, or Strings.isNullOrEmpty
etc), IMO it's much better for your project to just implement the thing yourself and avoid extra dependency.
Upvotes: 0
Reputation: 35457
Apparently you insist on having Predicate
s, which makes absolutely no sense in your use case. So maaartinus' answer is correct, but doesn't provide the answer with predicates. Here is a solution with predicates.
Predicate<Iterable<?>> anyIsNull = new Predicate<Iterable<?>>() {
@Override public boolean apply(Iterable<?> it) {
return Iterables.any(it, Predicates.isNull());
}
};
Predicate<Iterable<?>> allAreNull = new Predicate<Iterable<?>>() {
@Override public boolean apply(Iterable<?> it) {
return Iterables.all(it, Predicates.isNull());
}
};
Usage:
bool1 = anyIsNull.apply(Arrays.asList(obj1, obj2, obj3));
bool2 = allAreNull.apply(Arrays.asList(obj1, obj2, obj3));
Upvotes: 0
Reputation: 46472
I'm not sure what you want, but the answer is most probably: Yes, but it makes little sense.
You can use
FluentIterable<Object> it =
FluentIterable.from(Lists.newArrayList(obj1, obj2, obj3));
boolean allNull = it.allMatch(Predicates.isNull());
boolean anyNull = it.anyMatch(Predicates.isNull());
but be assured that it's both much less readable and much slower than doing it the normal way.
Upvotes: 4