001/*-------------------------------------------------------------------------+
002|                                                                          |
003| Copyright 2005-2011 The ConQAT Project                                   |
004|                                                                          |
005| Licensed under the Apache License, Version 2.0 (the "License");          |
006| you may not use this file except in compliance with the License.         |
007| You may obtain a copy of the License at                                  |
008|                                                                          |
009|    http://www.apache.org/licenses/LICENSE-2.0                            |
010|                                                                          |
011| Unless required by applicable law or agreed to in writing, software      |
012| distributed under the License is distributed on an "AS IS" BASIS,        |
013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
014| See the License for the specific language governing permissions and      |
015| limitations under the License.                                           |
016+-------------------------------------------------------------------------*/
017package org.conqat.lib.commons.predicate;
018
019import java.util.ArrayList;
020import java.util.Collection;
021import java.util.List;
022import java.util.function.Predicate;
023import java.util.stream.Collectors;
024
025import org.conqat.lib.commons.collections.Pair;
026
027/**
028 * Utility methods for working with predicates.
029 */
030public class PredicateUtils {
031
032        /**
033         * Returns all input elements that are contained in the set described by the
034         * predicate.
035         * 
036         * @param <T>
037         *            Type in collection.
038         */
039        public static <T> List<T> obtainContained(Collection<T> input, Predicate<? super T> predicate) {
040                return input.stream().filter(predicate).collect(Collectors.toCollection(ArrayList::new));
041        }
042
043        /**
044         * Efficiently splits the list of input elements into two lists.<br/>
045         * 
046         * The first consists of all input elements that are contained in the set
047         * described by the predicate.<br/>
048         * The second consists of all input elements that are <b>not</b> contained in
049         * the set described by the predicate.<br />
050         * 
051         * Efficiently in this case means that only one iteration through the list is
052         * needed to split into two lists.
053         * 
054         * @param input
055         *            the list of input elements.
056         * @param predicate
057         *            the {@link Predicate} used to decide containment.
058         */
059        public static <T> Pair<List<T>, List<T>> splitContainedNonContained(Collection<T> input,
060                        Predicate<? super T> predicate) {
061
062                List<T> contained = new ArrayList<>();
063                List<T> nonContained = new ArrayList<>();
064
065                for (T t : input) {
066                        if (predicate.test(t)) {
067                                contained.add(t);
068                        } else {
069                                nonContained.add(t);
070                        }
071                }
072                return new Pair<>(contained, nonContained);
073        }
074
075        /**
076         * Returns all input elements that are <b>not</b> contained in the set described
077         * by the predicate.
078         */
079        public static <T> List<T> obtainNonContained(Collection<T> input, Predicate<? super T> predicate) {
080                return obtainContained(input, predicate.negate());
081        }
082
083        /** Returns a predicate that always returns true. */
084        public static <T> Predicate<T> alwaysTrue() {
085                return t -> true;
086        }
087
088        /**
089         * Negates the given predicate (returns false if the given predicate returns
090         * true and vice versa).
091         */
092        public static <T> Predicate<T> not(Predicate<T> predicate) {
093                return t -> !predicate.test(t);
094        }
095}