diff --git a/org.fortiss.tooling.common/trunk/src/org/fortiss/tooling/common/util/.ratings b/org.fortiss.tooling.common/trunk/src/org/fortiss/tooling/common/util/.ratings index f4fa31ae4654644f1701a1d484265e044e07c783..a458f45448a1a611a32fa89da24026ddade9f5d6 100644 --- a/org.fortiss.tooling.common/trunk/src/org/fortiss/tooling/common/util/.ratings +++ b/org.fortiss.tooling.common/trunk/src/org/fortiss/tooling/common/util/.ratings @@ -1 +1 @@ -LambdaUtils.java f822288f446bbea584a6b958841a1729a73c5b13 YELLOW +LambdaUtils.java 83ee286ec8f5de7aa43775a4b5d20e3fe41c95c2 YELLOW diff --git a/org.fortiss.tooling.common/trunk/src/org/fortiss/tooling/common/util/LambdaUtils.java b/org.fortiss.tooling.common/trunk/src/org/fortiss/tooling/common/util/LambdaUtils.java index 8e07c203c71b398c8a5e5f352f637d00f0d5b044..a9ecd7cf80660c0e3626b85c16e82e2c504884ac 100644 --- a/org.fortiss.tooling.common/trunk/src/org/fortiss/tooling/common/util/LambdaUtils.java +++ b/org.fortiss.tooling.common/trunk/src/org/fortiss/tooling/common/util/LambdaUtils.java @@ -15,13 +15,16 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.common.util; +import static java.util.stream.Collectors.toList; import static java.util.stream.StreamSupport.stream; +import static org.conqat.lib.commons.reflect.ReflectionUtils.isInstanceOfAll; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; @@ -125,11 +128,56 @@ public class LambdaUtils { * Filter to apply. * @return Filtered collection as a List. */ - public static <T, S extends T> List<T> filterList(Collection<S> collection, - Predicate<S> filter) { + public static <T, S extends T> List<T> + filterList(Collection<S> collection, Predicate<S> filter) { return filterStream(collection, filter).collect(Collectors.toList()); } + /** + * Filters a {@link Collection} of {@code types} by the provided type {@code classifiers} . + * + * @param types + * Collection of types to be filtered + * @param classifiers + * Queried type classifiers + * @return Sub-{@link Collection} of {@code types} that is derived from all {@code classifiers}. + */ + @SafeVarargs + public static <T, C> Collection<Class<? extends T>> filterTypes( + Collection<Class<? extends T>> types, Class<? extends C>... classifiers) { + + // Checks if a single type is of the given single classifier type and returns the + // result as a Boolean. Cannot be implemented as a BiPredicate since "currying" / partial + // evaluation of (Bi)Predicates does not seem to be supported by Java 8+. + BiFunction<Class<? extends T>, Class<? extends C>, Boolean> isOfClassifier = + (t, c) -> c.isAssignableFrom(t); + + // Applies isOfType for all provided "classifiers" to a single type. The "orElse" + // handles the case that no "classifiers" have been provided. + Predicate<Class<? extends T>> typeClassifierFilter = + t -> Stream.of(classifiers).map(c -> isOfClassifier.apply(t, c)) + .reduce((b1, b2) -> b1 && b2).orElse(true); + + return types.stream().filter(typeClassifierFilter).collect(toList()); + } + + /** + * Filters a {@link Collection} of {@code elements} by the provided type {@code classifiers} . + * + * @param elements + * Collection of elements to be filtered + * @param classifiers + * Queried type classifiers + * @return Sub-{@link Collection} of {@code elements} that is an instance of all + * {@code classifiers}. + */ + @SafeVarargs + public static <T, C> Collection<T> filterByTypes(Collection<T> elements, + Class<? extends C>... classifiers) { + + return elements.stream().filter(e -> isInstanceOfAll(e, classifiers)).collect(toList()); + } + /** * Filters the elements of the given {@code inCol} collection based on their type by the given * {@code typeFilter}. The matching elements are added to the given {@code outCol} collection @@ -252,8 +300,8 @@ public class LambdaUtils { * Supplier for the output {@link Collection}, e.g. TreeSet::new. * @return Collection of mapping results. */ - public static <S, T, R extends Stream<S>, U extends Collection<S>> Collection<S> - flatMapInOut(Collection<T> inColl, Function<T, R> mapper, Supplier<U> sup) { + public static <S, T, R extends Stream<S>, U extends Collection<S>> Collection<S> flatMapInOut( + Collection<T> inColl, Function<T, R> mapper, Supplier<U> sup) { return inColl.parallelStream().flatMap(mapper).collect(Collectors.toCollection(sup)); }