Question

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)

Was it helpful?

Solution

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.

OTHER TIPS

Apparently you insist on having Predicates, 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));

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.

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