J'ai une méthode pour un filtre par type, il obtient en entrée Collection > collection
et Class
. Je veux remplacer FluentIterable
par le Stream
.
public static <T> List<T> typeFilter(final Collection<?> filter, final Class<T> classType) { return (List<T>) filter.stream() .filter(Objects::nonNull) .map(Object.class::cast) .collect(Collectors.toList()); }
J'ai essayé avec cette solution:
public static <T> List<T> filterByType(final Collection<?> filerCollection, final Class<T> classType) { return FluentIterable.from(filerCollection).filter(classType).toList(); }
4 Réponses :
Vous devriez utiliser classType :: cast
car ici vous utilisez Object.class :: cast
qui ne fait essentiellement rien
public static <T> List<T> typeFilter(final Collection<?> filter, final Class<T> classType) { return filter.stream() .filter(Objects::nonNull) .map(classType::cast) .collect(Collectors.toList()); }
Et pour être encore meilleur, ajoutez un filtre (classType :: isInstance)
à votre chaînage de méthodes
Regardez attentivement ce que FluentIterable :: filter (Class
le fait et le compare avec mappe chaque élément au classType
avec diffusion. Votre intention est de filtrer ces éléments de classType
.
Ensuite, le classType :: cast
doit être utilisé à la place de Object.class :: cast code> car la classe désirée est déjà passée par
Class
et peut être utilisée directement comme référence de méthode. Le Object.class :: cast
convertit en un Object
parent dont chaque objet hérite.
Voici ce que vous voulez:
< pre> XXX Modifier: comme mentionné dans une autre réponse , le filtre (classType :: isInstance)
peut également être utilisé.
Vous avez oublié de vérifier si vos éléments sont même de type T
. C'est à dire. vous devez d'abord filtrer ces éléments:
return filter.stream() .filter(classType::isInstance) // only keep elements of type T .map(classType::cast) // safely cast from Object to T .collect(Collectors.toList()); // collect into a List<T>
La classe # isInstance ()
prend également en charge directement les valeurs null
, donc vous ne pas besoin d'utiliser filter(Object::nonNull)
.
Une autre chose que vous pouvez faire (bien que ce soit probablement un peu moins efficace que de le faire en deux étapes) est de définir quelque chose comme ceci:
return filter.stream() .flatMap(instancesOf(classType)) .collect(toList());
puis de l'utiliser comme ceci: p>
public static <T> Function<Object, Stream<T>> instancesOf(Class<T> c) { return o -> c.isInstance(o) ? Stream.of(c.cast(o)) : Stream.empty(); }