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();
}