import java.util.Arrays;
import java.util.Objects;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
class PredicateExample {
public static void main
(String[] args
) { Stream<Animal> greenAnimals = Stream.<Animal>of()
.filter(
MultiPred.
ofOr(Animal
::getColor,
Color.
WHITE::equals,
Color.
GREEN::equals
) .or(
MultiPred.of(Animal::getType, AnimalType.CARNIVORE::equals)
.and(Animal::canFly) // we can chain custom Predicates with regular ones
)
.or(
MultiPred.of(Animal::getType, AnimalType.HERBIVORE::equals)
.
and(MultiPred.
of(Animal
::getColor,
Color.
PURPLE::equals
) .or(Animal::canSwim)
)
)
);
System.
out.
println("No errors"); }
}
class MultiPred {
@SafeVarargs
public static <T, K> Predicate<T> ofAnd(Function<T, K> keyExtractor,
Predicate<K>... predicates) {
return of(keyExtractor, k -> true, Predicate::and, predicates);
}
@SafeVarargs
public static <T, K> Predicate<T> ofOr(Function<T, K> keyExtractor,
Predicate<K>... predicates) {
return of(keyExtractor, k -> false, Predicate::or, predicates);
}
@SafeVarargs
public static <T, K> Predicate<T> of(Function<T, K> keyExtractor,
Predicate<K> identity,
BinaryOperator<Predicate<K>> op,
Predicate<K>... predicates) {
Objects.requireNonNull(predicates);
Predicate
<K
> predicate
= Arrays.
stream(predicates
).
reduce(identity, op
);
return of(keyExtractor, predicate);
}
public static <T, K> Predicate<T> of(Function<T, K> keyExtractor,
Predicate<K> predicate) {
Objects.requireNonNull(keyExtractor);
Objects.requireNonNull(predicate);
return t -> predicate.test(keyExtractor.apply(t));
}
}
enum Color { WHITE, GREEN, PURPLE
} enum AnimalType { HERBIVORE, CARNIVORE }
class Animal {
final AnimalType type;
final boolean canSwim, canFly;
Animal
(AnimalType type,
Color color,
boolean canSwim,
boolean canFly
) { this.type = type;
this.color = color;
this.canSwim = canSwim;
this.canFly = canFly;
}
public AnimalType getType() { return type; }
public Color getColor
() { return color
; } public boolean canSwim() { return canSwim; }
public boolean canFly() { return canFly; }
}
aW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuT2JqZWN0czsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5CaW5hcnlPcGVyYXRvcjsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5GdW5jdGlvbjsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi5QcmVkaWNhdGU7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLlN0cmVhbTsKCmNsYXNzIFByZWRpY2F0ZUV4YW1wbGUgewogIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKICAgIFN0cmVhbTxBbmltYWw+IGdyZWVuQW5pbWFscyA9IFN0cmVhbS48QW5pbWFsPm9mKCkKICAgICAgICAuZmlsdGVyKAogICAgICAgICAgICBNdWx0aVByZWQub2ZPcihBbmltYWw6OmdldENvbG9yLCBDb2xvci5XSElURTo6ZXF1YWxzLCBDb2xvci5HUkVFTjo6ZXF1YWxzKQogICAgICAgICAgICAgICAgLm9yKAogICAgICAgICAgICAgICAgICAgIE11bHRpUHJlZC5vZihBbmltYWw6OmdldFR5cGUsIEFuaW1hbFR5cGUuQ0FSTklWT1JFOjplcXVhbHMpCiAgICAgICAgICAgICAgICAgICAgLmFuZChBbmltYWw6OmNhbkZseSkgLy8gd2UgY2FuIGNoYWluIGN1c3RvbSBQcmVkaWNhdGVzIHdpdGggcmVndWxhciBvbmVzCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAub3IoCiAgICAgICAgICAgICAgICAgICAgTXVsdGlQcmVkLm9mKEFuaW1hbDo6Z2V0VHlwZSwgQW5pbWFsVHlwZS5IRVJCSVZPUkU6OmVxdWFscykKICAgICAgICAgICAgICAgICAgICAuYW5kKE11bHRpUHJlZC5vZihBbmltYWw6OmdldENvbG9yLCBDb2xvci5QVVJQTEU6OmVxdWFscykKICAgICAgICAgICAgICAgICAgICAgICAgLm9yKEFuaW1hbDo6Y2FuU3dpbSkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICApCiAgICAgICAgKTsKICAgIFN5c3RlbS5vdXQucHJpbnRsbigiTm8gZXJyb3JzIik7CiAgfQp9CmNsYXNzIE11bHRpUHJlZCB7CiAgQFNhZmVWYXJhcmdzCiAgcHVibGljIHN0YXRpYyA8VCwgSz4gUHJlZGljYXRlPFQ+IG9mQW5kKEZ1bmN0aW9uPFQsIEs+IGtleUV4dHJhY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJlZGljYXRlPEs+Li4uIHByZWRpY2F0ZXMpIHsKCiAgICAgIHJldHVybiBvZihrZXlFeHRyYWN0b3IsIGsgLT4gdHJ1ZSwgUHJlZGljYXRlOjphbmQsIHByZWRpY2F0ZXMpOwogIH0KCiAgQFNhZmVWYXJhcmdzCiAgcHVibGljIHN0YXRpYyA8VCwgSz4gUHJlZGljYXRlPFQ+IG9mT3IoRnVuY3Rpb248VCwgSz4ga2V5RXh0cmFjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByZWRpY2F0ZTxLPi4uLiBwcmVkaWNhdGVzKSB7CgogICAgICByZXR1cm4gb2Yoa2V5RXh0cmFjdG9yLCBrIC0+IGZhbHNlLCBQcmVkaWNhdGU6Om9yLCBwcmVkaWNhdGVzKTsKICB9CgogIEBTYWZlVmFyYXJncwogIHB1YmxpYyBzdGF0aWMgPFQsIEs+IFByZWRpY2F0ZTxUPiBvZihGdW5jdGlvbjxULCBLPiBrZXlFeHRyYWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByZWRpY2F0ZTxLPiBpZGVudGl0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmluYXJ5T3BlcmF0b3I8UHJlZGljYXRlPEs+PiBvcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJlZGljYXRlPEs+Li4uIHByZWRpY2F0ZXMpIHsKCiAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwocHJlZGljYXRlcyk7CgogICAgICBQcmVkaWNhdGU8Sz4gcHJlZGljYXRlID0gQXJyYXlzLnN0cmVhbShwcmVkaWNhdGVzKS5yZWR1Y2UoaWRlbnRpdHksIG9wKTsKCiAgICAgIHJldHVybiBvZihrZXlFeHRyYWN0b3IsIHByZWRpY2F0ZSk7CiAgfQoKICBwdWJsaWMgc3RhdGljIDxULCBLPiBQcmVkaWNhdGU8VD4gb2YoRnVuY3Rpb248VCwgSz4ga2V5RXh0cmFjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVkaWNhdGU8Sz4gcHJlZGljYXRlKSB7CgogICAgICBPYmplY3RzLnJlcXVpcmVOb25OdWxsKGtleUV4dHJhY3Rvcik7CiAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwocHJlZGljYXRlKTsKCiAgICAgIHJldHVybiB0IC0+IHByZWRpY2F0ZS50ZXN0KGtleUV4dHJhY3Rvci5hcHBseSh0KSk7CiAgfQp9CmVudW0gQ29sb3IgeyBXSElURSwgR1JFRU4sIFBVUlBMRSB9CmVudW0gQW5pbWFsVHlwZSB7IEhFUkJJVk9SRSwgQ0FSTklWT1JFIH0KY2xhc3MgQW5pbWFsIHsKICBmaW5hbCBBbmltYWxUeXBlIHR5cGU7CiAgZmluYWwgQ29sb3IgY29sb3I7CiAgZmluYWwgYm9vbGVhbiBjYW5Td2ltLCBjYW5GbHk7CgogIEFuaW1hbChBbmltYWxUeXBlIHR5cGUsIENvbG9yIGNvbG9yLCBib29sZWFuIGNhblN3aW0sIGJvb2xlYW4gY2FuRmx5KSB7CiAgICB0aGlzLnR5cGUgPSB0eXBlOwogICAgdGhpcy5jb2xvciA9IGNvbG9yOwogICAgdGhpcy5jYW5Td2ltID0gY2FuU3dpbTsKICAgIHRoaXMuY2FuRmx5ID0gY2FuRmx5OwogIH0KICBwdWJsaWMgQW5pbWFsVHlwZSBnZXRUeXBlKCkgeyByZXR1cm4gdHlwZTsgfQogIHB1YmxpYyBDb2xvciBnZXRDb2xvcigpIHsgcmV0dXJuIGNvbG9yOyB9CiAgcHVibGljIGJvb2xlYW4gY2FuU3dpbSgpIHsgcmV0dXJuIGNhblN3aW07IH0KICBwdWJsaWMgYm9vbGVhbiBjYW5GbHkoKSB7IHJldHVybiBjYW5GbHk7IH0KfQo=