J'ai essayé de créer une méthode qui applique plusieurs filtres à la fois avec l'API Java Stream. Cela vous convient-il?

Avant

Par exemple, supposons que vous ayez un DTO comme celui-ci:

/**
 *Entrée avec plusieurs conditions de filtre.
 * <p>
 ** En fait, cela peut être plus compliqué ou complexe...
 */
@Data
class InputDto {

    /**Conditions utilisées pour les filtres 1*/
    private boolean conditions1;
    /**Condition 2 utilisée pour le filtre*/
    private boolean conditions2;
    /**Condition 3 utilisée pour le filtre*/
    private boolean conditions3;
    /**Condition utilisée pour le filtre 4*/
    private boolean conditions4;
    /**Condition utilisée pour le filtre 5*/
    private boolean conditions5;

    // ...
}

Lors de l'agrégation de cette liste DTO par condition, je pense qu'elle s'écrit souvent comme suit.

private void count(List<InputDto> inputs) {

    //Nombre de cas où la condition 1 est appliquée à l'entrée
    inputs.stream()
        .filter(i -> i.isConditions1())
        .count();

    //Nombre de cas où la condition 2 est appliquée à l'entrée
    inputs.stream()
        .filter(i -> i.isConditions2())
        .count();

    //Condition 3 pour l'entrée,Nombre de cas lorsque 4 est appliqué
    inputs.stream()
        .filter(i -> i.isConditions3())
        .filter(i -> i.isConditions4())
        .count();

    //Condition 1 pour l'entrée, 3,Nombre de cas lorsque 5 est appliqué
    inputs.stream()
        .filter(i -> i.isConditions1())
        .filter(i -> i.isConditions3())
        .filter(i -> i.isConditions5())
        .count();
}

Alors

/**
 *Sortie avec résultats agrégés.
 */
@Data
class OutputDto {

    /**Nombre de cas auxquels la condition 1 a été appliquée*/
    private Long count1;
    /**Nombre de cas auxquels la condition 2 est appliquée*/
    private Long count2;
    /**Condition 3,Nombre de cas auxquels 4 a été appliqué*/
    private Long count3And4;
    /**Condition 1, 3,Nombre de cas auxquels 5 a été appliqué*/
    private Long count1And3And5;

    // ...
}

Lorsque vous remplissez le DTO de sortie comme ceci,

private void makeOutput(List<InputDto> inputs) {
        
    OutputDto.builder()
    	.count1(inputs.stream()
                .filter(i -> i.isConditions1())
                .count())
    	.count2(inputs.stream()
                .filter(i -> i.isConditions2())
                .count())
    	.count3And4(inputs.stream()
                    .filter(i -> i.isConditions3())
                    .filter(i -> i.isConditions4())
                    .count())
    	.count1And3And5(inputs.stream()
                        .filter(i -> i.isConditions1())
                        .filter(i -> i.isConditions3())
                        .filter(i -> i.isConditions5())
                        .count())
    	.build();
}

Est-ce que c'est comme ça?

La condition est boolean donc je peux toujours la lire, mais je n'ai pas pu la voir quand le DTO de l'enfant est sorti:

Je me suis donc demandé si ce serait plus facile à lire.

J'ai pensé à une méthode que je pensais facile à lire

Pensées

L'API Stream de Java est pratique, mais si vous l'écrivez dans une liste telle que des expressions lambda, elle peut être difficile à lire.: Disappointed_relieved:

J'ai donc pensé à diviser les méthodes pour pouvoir ** comprendre ce que je voulais faire **.

Filtre long et agrégat(List<InputDto>Liste des entrées, Predicate<? super InputDto>...Beaucoup de filtres) {
    //Gonyo Gonyo
Nombre de retours;
}

Comme ça.

De plus, si vous écrivez «beaucoup de filtres» dans une expression lambda, cela restera difficile à voir, c'est donc aussi une méthode.

Predicate<? super InputDto>Un certain filtre() {
entrée de retour->Filtrage avec entrées;
}
// ...réduction

De cette façon, quand vous l'utilisez

Filtrer et agréger(Liste des entrées,Un certain filtre(),Autres filtres());

C'est comme ** Facile à lire et plus court! J'ai pensé **.

Ce que vous avez mis en œuvre

La méthode «filtrer et agréger»

/**
 *Appliquer tous les filtres passés avec des arguments variables à la liste des entrées et renvoyer le nombre.
 *
 * @param inputs
 * @param filters
 * @nombre de cas après application du filtre de retour
 */
private final Long filterCount(List<InputDto> inputs, Predicate<? super InputDto>... filters) {
    Stream<InputDto> work = inputs.stream();
    for (Predicate<? super InputDto> filter : filters) {
        work = work.filter(filter);
    }
    return work.count();
}

Je l'ai implémenté comme ça.

Puisque Stream ne peut pas être réutilisé, cela ressemble à un filtrage avec for-each statement.

La méthode certains filtres

/**
 * @return {@link InputDto#isConditions1()}Filtrer en utilisant
 */
private Predicate<? super InputDto> filter1() {
    return i -> i.isConditions1();
}

/**
 * @return {@link InputDto#isConditions2()}Filtrer en utilisant
 */
private Predicate<? super InputDto> filter2() {
    return i -> i.isConditions2();
}

// ...Omission

/**
 * @return {@link InputDto#isConditions5()}Filtrer en utilisant
 */
private Predicate<? super InputDto> filter5() {
    return i -> i.isConditions5();
}

Nous l'avons préparé au niveau minimum pour qu'il puisse être réutilisé.

Je l'ai utilisé

Si vous réécrivez le processus d'emballage dans la sortie qui apparaissait dans l'introduction

private void makeOutput(List<InputDto> inputs) {
        
    OutputDto.builder()
    	.count1(filterCount(inputs, filter1()))
    	.count2(filterCount(inputs, filter2()))
    	.count3And4(filterCount(inputs, filter3(), filter4()))
    	.count1And3And5(filterCount(inputs, filter1(), filter3(), filter5()))
    	.build();
}

Je me sens comme cela.

Comment c'est? Facile à lire: réflexion :: question:

Est-ce que ça allait?

C'était le code que j'avais écrit il y a longtemps, mais je me suis souvenu que d'autres personnes disaient que c'était utile.

J'étais content parce que je l'ai écrit avec beaucoup de peine, mais ** Y a-t-il une meilleure façon de l'écrire? La question s'est posée et j'ai écrit l'article.

Les programmeurs Java dans le monde!

Indépendamment de l'API Stream

Il existe une telle manière d'écrire - c'est facile à lire -

Je vous serais reconnaissant si vous pouviez me le faire savoir! : Miam:

** J'ai un exemple de code qui s'intègre parfaitement dans la section des commentaires! S'il vous plaît voir si vous êtes intéressé! !! ** **

Remarquer

Recommended Posts

J'ai essayé de créer une méthode qui applique plusieurs filtres à la fois avec l'API Java Stream. Cela vous convient-il?
J'ai essayé de créer un environnement de développement java8 avec Chocolatey
J'ai essayé de casser le bloc avec java (1)
J'ai essayé de créer une fonction / écran d'administrateur de site commercial avec Java et Spring
[Azure] J'ai essayé de créer une application Java gratuitement ~ Se connecter avec FTP ~ [Débutant]
J'ai essayé de moderniser une application Java EE avec OpenShift.
[Rails] J'ai essayé de créer une mini application avec FullCalendar
J'ai essayé de créer un environnement de développement padrino avec Docker
Je veux écrire une boucle qui fait référence à un index avec l'API Stream de Java 8
Puisque la lecture de JdbcCodeList de TERASOLUNA est lente, j'ai essayé d'enregistrer plusieurs à la fois.
J'ai essayé d'interagir avec Java
J'ai essayé d'utiliser l'API Java8 Stream
[Java] J'ai essayé de faire un labyrinthe par la méthode de creusage ♪
J'ai essayé de créer une API Web qui se connecte à DB avec Quarkus
Je souhaite créer un SNS Web sombre avec Jakarta EE 8 avec Java 11
J'ai essayé de résumer l'API Stream
J'ai essayé de résoudre 10 questions précédentes sélectionnées qui devraient être résolues après l'inscription à AtCoder avec Java, API Stream
Quand j'ai voulu créer une méthode pour Premium Friday, c'était déjà dans l'API standard Java 8
J'ai créé un programme qui recherche la classe cible à partir du processus surchargé avec Java
[Java] J'ai installé JDBC et essayé de me connecter avec servlet + MySQL. (Il existe une version utilisant DAO / Bean)
J'ai essayé de créer un portefeuille avec AWS, Docker, CircleCI, Laravel [avec lien de référence]
[Java] J'ai essayé de me connecter en utilisant le pool de connexion avec Servlet (tomcat) & MySQL & Java
[Azure] J'ai essayé de créer une application Java pour la création d'applications Web gratuites - [Débutant]
J'ai essayé de faire une authentification de base avec Java
java j'ai essayé de casser un simple bloc
J'ai essayé de créer une application de clonage LINE
J'ai essayé de créer une compétence Alexa avec Java
J'ai essayé de créer un outil de comparaison des prix des produits Amazon dans le monde entier avec Java, l'API Amazon Product Advertising, l'API Currency (29/01/2017)
J'ai essayé ce que je voulais essayer avec Stream doucement.
J'ai essayé d'implémenter TCP / IP + BIO avec JAVA
[Java 11] J'ai essayé d'exécuter Java sans compiler avec javac
J'ai essayé de créer une fonction de connexion avec Java
J'ai essayé de dessiner une animation avec l'API Blazor + canvas
J'ai essayé OCR de traiter un fichier PDF avec Java
J'ai essayé d'implémenter Sterling Sort avec Java Collector
[Java] J'ai essayé de mettre en œuvre la recherche de produits de l'API Yahoo
Je veux faire une liste avec kotlin et java!
Je veux créer une fonction avec kotlin et java!
Créer un SlackBot avec AWS lambda et API Gateway en Java
Créer une méthode pour renvoyer le taux de taxe en Java
J'ai essayé de lier le chat avec le serveur de Minecraft avec l'API Discord
Même en Java, je veux afficher true avec un == 1 && a == 2 && a == 3
J'ai essayé de convertir une chaîne de caractères en un type LocalDate en Java
Il est maintenant temps de commencer avec l'API Stream
J'ai créé un client RESAS-API en Java
J'ai essayé OCR de traiter un fichier PDF avec Java part2
Convertir un tableau bidimensionnel au format csv avec l'API Java 8 Stream
J'ai essayé de pouvoir passer plusieurs objets avec Ractor
J'ai essayé d'implémenter le code pour apprendre plusieurs images à la fois dans la Watson Visual Recognition Collection en Java
Créer une méthode java [Memo] [java11]
[Java] Introduction à l'API Stream
Comment créer une méthode
J'ai essayé de créer une application cartographique simple dans Android Studio
Je ne peux pas créer une classe Java avec un nom spécifique dans IntelliJ
J'ai essayé de créer un environnement de développement Spring MVC sur Mac
Connexion à une base de données avec Java (partie 1) Peut-être la méthode de base
J'ai essayé de comprendre comment la méthode des rails "redirect_to" est définie
Création d'une méthode pour demander Premium Friday (version Java 8)