All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.strobel.core.Predicates Maven / Gradle / Ivy

There is a newer version: 2.5.0.Final
Show newest version
/*
 * Predicates.java
 *
 * Copyright (c) 2013 Mike Strobel
 *
 * This source code is subject to terms and conditions of the Apache License, Version 2.0.
 * A copy of the license can be found in the License.html file at the root of this distribution.
 * By using this source code in any fashion, you are agreeing to be bound by the terms of the
 * Apache License, Version 2.0.
 *
 * You must not remove this notice, or any other, from this software.
 */

package com.strobel.core;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Static utility methods pertaining to {@code Predicate} instances.
 *
 * 

All of the returned predicates are serializable if given serializable * parameters. */ @SuppressWarnings("unchecked") public final class Predicates { /** * a predicate that evaluates to {@code true} if the reference * being tested is {@code null}. */ public static final Predicate IS_NULL = new Predicate() { @Override public boolean test(final Object o) { return o == null; } }; /** * a predicate that evaluates to {@code true} if the reference * being tested is not {@code null}. */ public static final Predicate NON_NULL = new Predicate() { @Override public boolean test(final Object o) { return o != null; } }; /** * a predicate who's result is always {@code false}. */ public static final Predicate FALSE = new Predicate() { @Override public boolean test(final Object o) { return false; } }; /** * a predicate who's result is always {@code true}. */ public static final Predicate TRUE = new Predicate() { @Override public boolean test(final Object o) { return true; } }; /** * singleton utils */ private Predicates() { throw new AssertionError("No instances!"); } /** * Returns a predicate that evaluates to {@code true} if the reference * being tested is {@code null}. * * @return a predicate that evaluates to {@code true} if the reference * being tested is {@code null} */ public static Predicate isNull() { return (Predicate) IS_NULL; } /** * Returns a predicate that evaluates to {@code true} if the reference * being tested is non-{@code null}. * * @return a predicate that evaluates to {@code true} if the reference * being tested is is non-{@code null} */ public static Predicate nonNull() { return (Predicate) NON_NULL; } /** * Returns a predicate who's result is always {@code false}. * * @return a predicate who's result is always {@code false}. */ public static Predicate alwaysFalse() { return (Predicate) FALSE; } /** * Returns a predicate who's result is always {@code true}. * * @return a predicate who's result is always {@code true}. */ public static Predicate alwaysTrue() { return (Predicate) TRUE; } /** * Returns a predicate that evaluates to {@code true} if the object being * tested is an instance of the provided class. If the object being tested * is {@code null} this predicate evaluates to {@code false}. * * @param clazz The target class to be matched by the predicate. * @return a predicate that evaluates to {@code true} if the object being * tested is an instance of the provided class */ public static Predicate instanceOf(final Class clazz) { return new Predicate() { @Override public boolean test(final T o) { return clazz.isInstance(o); } }; } /** * Returns a predicate that who's result is {@code target == object}. * * @param the type of predicate values. * @param target The target value to be compared for identity equality. * @return a predicate that who's result is {@code target == object} */ public static Predicate isSame(final T target) { return new Predicate() { @Override public boolean test(final T t) { return t == target; } }; } /** * Returns a predicate who's result matches * {@code Objects.equals(target, t)}. * * @param the type of predicate values. * @param target The target value to be compared for equality. * @return a predicate who's result matches {@code Objects.equals(target, t)} */ public static Predicate isEqual(final T target) { if (null == target) return Predicates.isNull(); return new Predicate() { @Override public boolean test(final T t) { return target.equals(t); } }; } /** * Creates a predicate that evaluates to {@code true} if the tested object * is a member of the provided collection. The collection is not defensively * copied, so changes to it will alter the behavior of the predicate. * * @param Type of predicate values. * @param target the collection against which objects will be tested. * @return a predicate that evaluates to {@code true} if the tested object * is a member of the provided collection. The collection is not defensively * copied, so changes to it will alter the behavior of the predicate. */ public static Predicate contains(final Collection target) { return new Predicate() { @Override public boolean test(final T t) { return target.contains(t); } }; } /** * Creates a predicate that evaluates to {@code true} if the tested object * is a key in the provided map. The map is not defensively copied, so changes * to it will alter the behavior of the predicate. * * @param Type of predicate values. * @param target the map against which objects will be tested. * @return a predicate that evaluates to {@code true} if the tested object * is a key in the provided map. The map is not defensively copied, so changes * to it will alter the behavior of the predicate. */ public static Predicate containsKey(final Map target) { return new Predicate() { @Override public boolean test(final T t) { return target.containsKey(t); } }; } /** * Returns a predicate that evaluates to {@code true} if the provided * predicate evaluates to {@code false} * * @param the type of values evaluated by the predicate. * @param predicate The predicate to be evaluated. * @return A predicate who's result is the logical inverse of the provided * predicate. */ public static > Predicate negate(final P predicate) { return new Predicate() { @Override public boolean test(final T t) { return !predicate.test(t); } }; } /** * Returns a predicate that evaluates to {@code true} if all of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will terminate upon the first * {@code false} predicate. * * @param the type of values evaluated by the predicates. * @param first initial component predicate to be evaluated. * @param second additional component predicate to be evaluated. * @return A predicate who's result is {@code true} iff all component * predicates are {@code true}. */ public static > Predicate and(final Predicate first, final P second) { if(first != null && first == second) { return first; } Objects.requireNonNull(first); Objects.requireNonNull(second); return new Predicate() { @Override public boolean test(final T t) { //noinspection ConstantConditions return first.test(t) && second.test(t); } }; } /** * Returns a predicate that evaluates to {@code true} if all of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will end upon the first * {@code false} predicate. * * @param the type of values evaluated by the predicates. * @param components The predicates to be evaluated. * @return A predicate who's result is {@code true} iff all component * predicates are {@code true}. */ public static > Predicate and(final Iterable

components) { final List

predicates = safeCopyOf(components); if(predicates.isEmpty()) { throw new IllegalArgumentException("no predicates"); } return new Predicate() { @Override public boolean test(final T t) { for (final P predicate : predicates) { if (!predicate.test(t)) { return false; } } return true; } }; } /** * Returns a predicate that evaluates to {@code true} if all of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will end upon the first * {@code false} predicate. * * @param the type of values evaluated by the predicates. * @param components The predicates to be evaluated. * @return A predicate who's result is {@code true} iff all component * predicates are {@code true}. */ static > Predicate and(final P first, final Iterable

components) { final List

predicates = safeCopyOf(first, components); return new Predicate() { @Override public boolean test(final T t) { for (final P predicate : predicates) { if (!predicate.test(t)) { return false; } } return true; } }; } /** * Returns a predicate that evaluates to {@code true} if all of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will end upon the first * {@code false} predicate. * * @param the type of values evaluated by the predicates. * @param components The predicates to be evaluated. A copy is made of the * components. * @return A predicate who's result is {@code true} iff all component * predicates are {@code true}. */ @SafeVarargs public static > Predicate and(final P... components) { final P[] predicates = safeCopyOf(components); if(0 == predicates.length) { throw new IllegalArgumentException("no predicates"); } return new Predicate() { @Override public boolean test(final T t) { for (final P predicate : predicates) { if (!predicate.test(t)) { return false; } } return true; } }; } /** * Returns a predicate that evaluates to {@code true} if all of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will end upon the first * {@code false} predicate. * * @param the type of values evaluated by the predicates. * @param first first predicate to be evaluated. * @param components The predicates to be evaluated. A copy is made of the * components. * @return A predicate who's result is {@code true} iff all component * predicates are {@code true}. */ @SafeVarargs static > Predicate and(final P first, final P... components) { final P[] predicates = safeCopyOf(first, components); if(0 == predicates.length) { throw new IllegalArgumentException("no predicates"); } return new Predicate() { @Override public boolean test(final T t) { for (final P predicate : predicates) { if (!predicate.test(t)) { return false; } } return true; } }; } /** * Returns a predicate that evaluates to {@code true} if any of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will end upon the first * {@code true} predicate. * * @param the type of values evaluated by the predicates. * @param first initial component predicate to be evaluated. * @param second additional component predicate to be evaluated. * @return A predicate who's result is {@code true} if any component * predicate's result is {@code true}. */ public static > Predicate or(final Predicate first, final P second) { if(first != null && first == second) { return first; } Objects.requireNonNull(first); Objects.requireNonNull(second); return new Predicate() { @Override public boolean test(final T t) { //noinspection ConstantConditions return first.test(t) || second.test(t); } }; } /** * Returns a predicate that evaluates to {@code true} if any of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will end upon the first * {@code true} predicate. * * @param the type of values evaluated by the predicates. * @param components The predicates to be evaluated. A copy is made of the * components. * @return A predicate who's result is {@code true} if any component * predicate's result is {@code true}. */ public static > Predicate or(final Iterable

components) { final List

predicates = safeCopyOf(components); if(predicates.isEmpty()) { throw new IllegalArgumentException("no predicates"); } return new Predicate() { @Override public boolean test(final T t) { for (final P predicate : predicates) { if (predicate.test(t)) { return true; } } return false; } }; } /** * Returns a predicate that evaluates to {@code true} if any of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will end upon the first * {@code true} predicate. * * @param the type of values evaluated by the predicates. * @param components The predicates to be evaluated. A copy is made of the * components. * @return A predicate who's result is {@code true} if any component * predicate's result is {@code true}. */ static > Predicate or(final P first, final Iterable

components) { final List

predicates = safeCopyOf(first, components); return new Predicate() { @Override public boolean test(final T t) { for (final P predicate : predicates) { if (predicate.test(t)) { return true; } } return false; } }; } /** * Returns a predicate that evaluates to {@code true} if any of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will terminate upon the first * {@code true} predicate. * * @param the type of values evaluated by the predicates. * @param components The predicates to be evaluated. A copy is made of the * components. * @return A predicate who's result is {@code true} if any component * predicate's result is {@code true}. */ @SafeVarargs public static > Predicate or(final P... components) { final P[] predicates = safeCopyOf(components); if(0 == predicates.length) { throw new IllegalArgumentException("no predicates"); } return new Predicate() { @Override public boolean test(final T t) { for (final P predicate : predicates) { if (predicate.test(t)) { return true; } } return false; } }; } /** * Returns a predicate that evaluates to {@code true} if any of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will terminate upon the first * {@code true} predicate. * * @param the type of values evaluated by the predicates. * @param components The predicates to be evaluated. A copy is made of the * components. * @return A predicate who's result is {@code true} if any component * predicate's result is {@code true}. */ @SafeVarargs static > Predicate or(final Predicate first, final P... components) { final P[] predicates = safeCopyOf((P) first, components); return new Predicate() { @Override public boolean test(final T t) { for (final P predicate : predicates) { if (predicate.test(t)) { return true; } } return false; } }; } /** * Returns a predicate that evaluates to {@code true} if all or none of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will end if a predicate result * fails to match the first predicate's result. * * @param the type of values evaluated by the predicates. * @param first initial component predicate to be evaluated. * @param second additional component predicate to be evaluated. * @return a predicate that evaluates to {@code true} if all or none of the * component predicates evaluate to {@code true} */ public static > Predicate xor(final Predicate first, final P second) { if(null != first && first == second) { return alwaysFalse(); } Objects.requireNonNull(first); Objects.requireNonNull(second); return new Predicate() { @Override public boolean test(final T t) { //noinspection ConstantConditions return first.test(t) ^ second.test(t); } }; } /** * Returns a predicate that evaluates to {@code false} if all or none of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will end if a predicate result * fails to match the first predicate's result. * * @param the type of values evaluated by the predicates. * @param components The predicates to be evaluated. A copy is made of the * components. * @return a predicate that evaluates to {@code false} if all or none of the * component predicates evaluate to {@code true} */ public static > Predicate xor(final Iterable

components) { final List

predicates = safeCopyOf(components); if(predicates.isEmpty()) { throw new IllegalArgumentException("no predicates"); } return new Predicate() { @Override public boolean test(final T t) { Boolean initial = null; for (final P predicate : predicates) { if (null == initial) { initial = predicate.test(t); } else { if (!(initial ^ predicate.test(t))) { return true; } } } return false; } }; } /** * Returns a predicate that evaluates to {@code false} if all or none of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will terminate if a predicate result * fails to match the first predicate's result. * * @param the type of values evaluated by the predicates. * @param components The predicates to be evaluated. A copy is made of the * components. * @return a predicate that evaluates to {@code false} if all or none of the * component predicates evaluate to {@code true} */ @SafeVarargs public static > Predicate xor(final P... components) { final P[] predicates = safeCopyOf(components); if(0 == predicates.length) { throw new IllegalArgumentException("no predicates"); } return new Predicate() { @Override public boolean test(final T t) { Boolean initial = null; for (final P predicate : predicates) { if (null == initial) { initial = predicate.test(t); } else { if (!(initial ^ predicate.test(t))) { return true; } } } return false; } }; } /** * Returns a predicate that evaluates to {@code false} if all or none of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will end if a predicate result * fails to match the first predicate's result. * * @param the type of values evaluated by the predicates. * @param components The predicates to be evaluated. A copy is made of the * components. * @return a predicate that evaluates to {@code false} if all or none of the * component predicates evaluate to {@code true} */ @SafeVarargs static > Predicate xor(final Predicate first, final P... components) { final P[] predicates = safeCopyOf((P) first, components); return new Predicate() { @Override public boolean test(final T t) { Boolean initial = null; for (final P predicate : predicates) { if (null == initial) { initial = predicate.test(t); } else { if (!(initial ^ predicate.test(t))) { return true; } } } return false; } }; } /** * Returns a predicate that evaluates to {@code false} if all or none of the * component predicates evaluate to {@code true}. The components are * evaluated in order, and evaluation will end if a predicate result * fails to match the first predicate's result. * * @param the type of values evaluated by the predicates. * @param components The predicates to be evaluated. A copy is made of the * components. * @return a predicate that evaluates to {@code false} if all or none of the * component predicates evaluate to {@code true} */ static > Predicate xor(final Predicate first, final Iterable

components) { final List

predicates = safeCopyOf((P) first, components); return new Predicate() { @Override public boolean test(final T t) { Boolean initial = null; for (final P predicate : predicates) { if (null == initial) { initial = predicate.test(t); } else { if (!(initial ^ predicate.test(t))) { return true; } } } return false; } }; } @SafeVarargs private static T[] safeCopyOf(final T... array) { final T[] copy = Arrays.copyOf(array, array.length); for(final T each : copy) { Objects.requireNonNull(each); } return copy; } @SafeVarargs private static T[] safeCopyOf(final T first, final T... array) { final T[] copy = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length + 1); copy[0] = Objects.requireNonNull(first); System.arraycopy(array, 0, copy, 1, array.length); for(final T each : copy) { Objects.requireNonNull(each); } return copy; } private static List safeCopyOf(final T first, final Iterable iterable) { final ArrayList list = new ArrayList<>(); list.add(Objects.requireNonNull(first)); for (final T element : iterable) { list.add(Objects.requireNonNull(element)); } return list; } private static List safeCopyOf(final Iterable iterable) { final ArrayList list = new ArrayList<>(); for (final T element : iterable) { list.add(Objects.requireNonNull(element)); } return list; } }