2
votes

Remplacer goyave Fluent Iterables par Streams

J'ai une méthode pour un filtre par type, il obtient en entrée Collection > collection et Class tClass . 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();
}


0 commentaires

4 Réponses :


1
votes

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


0 commentaires

1
votes

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 car la classe désirée est déjà passée par Class classType 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é.


0 commentaires

4
votes

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).


0 commentaires

0
votes

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


0 commentaires