[JAVA] Créez une classe temporaire avec le nouvel Object () {}

introduction

La classe ʻObjectde Java est une classe très importante dans la superclasse de toutes les classes, mais n'est-il pas rare de se "nouveau"? Dans cet article, je vais vous montrer deux exemples de code oùnew Object ()` a du sens.

Définir une méthode dans une méthode

Voici un exemple de code décrit dans le commentaire «Implémentation d'une combinaison de mathématiques en Java --Qiita». Cette méthode énumère et renvoie «k» combinaisons à partir du tableau de chaînes «data».

    static List<String[]> combination(String[] data, int k) {
        List<String[]> result = new ArrayList<String[]>();
        combination(data, 0, new String[k], 0, result);
        return result;
    }

    static void combination(String[] data, int di, String[] comb, int ci, List<String[]> result) {
        if (ci == comb.length) {
            result.add(comb.clone());
            return;
        }
        for ( ; di <= data.length - (comb.length - ci); di++) {
            comb[ci] = data[di];
            combination(data, di + 1, comb, ci + 1, result);
        }
    }

Il se compose de deux méthodes, celle qui est appelée directement de l'extérieur est la «combinaison» à deux arguments, et la «combinaison» à cinq arguments est utilisée en interne. La «combinaison» à 5 arguments se rappelle d'elle-même, mais sur les 5 arguments, les 3 arguments («data», «comb», «result») spécifient exactement la même valeur que l'argument. Si Java peut définir des méthodes imbriquées, vous ne devriez pas avoir à écrire les mêmes arguments lors d'un appel de rappel. Malheureusement, vous ne pouvez pas imbriquer de méthodes en Java. Réécrivons-le donc en utilisant new Object ().

    static List<String[]> combination(String[] data, int k) {
        int length = data.length;
        List<String[]> result = new ArrayList<String[]>();
        String[] comb = new String[k];
        new Object() {
            void combination(int di, int ci) {
                if (ci == k) {
                    result.add(comb.clone());
                    return;
                }
                for (; di <= length - (k - ci); di++) {
                    comb[ci] = data[di];
                    combination(di + 1, ci + 1);
                }
            }
        }.combination(0, 0);
        return result;
    }

La «combinaison» à 5 arguments est écrite dans le «nouvel Object () {}» et les 3 arguments fixes («data», «comb», «result») sont supprimés. Le new Object () {} dans ce code définit une classe interne anonyme et crée en même temps une instance de cette classe. Le .combination (0, 0) après lenouvel Object () {}appelle la combinaison (int di, int ci) définie dans la classe interne. Les 3 variables fixes (data, comb, result) peuvent être référencées à partir de la classe interne, il n'est donc pas nécessaire de les passer comme arguments pour chaque appel. Je crée une instance inutile avec new Object (), mais la surcharge est faible car je n'en crée qu'une. La consommation de pile est réduite car il y a moins d'arguments sur l'appel de rappel.

Classe pour le stockage temporaire des données

Supposons que vous ayez une classe comme celle-ci:

public class Person {

    private final String name;
    private final String age;

    public Person(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return this.name;
    }

    public String getAge() {
        return this.age;
    }
}

De plus, supposons que vous ayez la liste suivante de Persons.

List<Person> list = List.of(
    new Person("Yamada", "18"),
    new Person("Ichikawa", "72"),
    new Person("Sato", "39"),
    new Person("Tanaka", "9"));

Pensez à trier ceci dans l'ordre croissant par «âge». Puisque ʻage` est une chaîne, il doit être écrit comme ceci pour le trier comme un entier.

    List<Person> result = list.stream()
        .sorted(Comparator.comparingInt(p -> Integer.parseInt(p.getAge())))
        .collect(Collectors.toList());

Cela fonctionne bien, mais ce n'est pas très efficace car ʻInteger.parseInt (p.getAge ()) est exécuté deux fois à chaque fois que les valeurs sont comparées. Même avec l'algorithme de tri rapide, ʻInteger.parseInt est exécuté $ 2n \ log n $ fois.

Map.Entry

L'appariement d'une instance de Person avec une version intégrale de ʻagerésout ce problème. Dans de tels cas, la classeMap.Entry` est souvent utilisée comme emplacement de stockage temporaire.

    List<Person> result = list.stream()
        .map(p -> Map.entry(Integer.parseInt(p.getAge()), p))
        .sorted(Comparator.comparingInt(Entry::getKey))
        .map(Entry::getValue)
        .collect(Collectors.toList());

L'entier ʻagen'a besoin d'être calculé qu'une seule fois, mais il n'est pas intuitivement clair oùMap.Entry` est utilisé.

Records Java 14 ajoute une fonctionnalité appelée Records qui facilite la définition de classes immuables pour le stockage de données. Si vous utilisez ceci, ce sera comme ça.

    record PersonWithAge(Person p, int age) {
        PersonWithAge(Person p) {
            this(p, Integer.parseInt(p.getAge()));
        }
    }

    List<Person> result = list.stream()
        .map(PersonWithAge::new)
        .sorted(Comparator.comparingInt(PersonWithAge::age))
        .map(PersonWithAge::p)
        .collect(Collectors.toList());

C'est plus facile à comprendre, mais cela semble aussi un peu exagéré car il définit une classe pour le stockage temporaire.

new Object() C'est ce qui se passe lorsque vous utilisez new Object ().

    List<Person> result = list.stream()
        .map(p -> new Object() {
            int intAge = Integer.parseInt(p.getAge());
            Person person = p;
        })
        .sorted(Comparator.comparingInt(obj -> obj.intAge))
        .map(obj -> obj.person)
        .collect(Collectors.toList());

new Object () {...} est un emplacement de stockage temporaire qui n'est valide que dans cette expression. Bien que ce soit une classe sans nom, elle est reconnue dans cette expression comme une classe à part entière avec les champs ʻintAge et person`.

Résumé

Comment était-ce? Vous pouvez voir que la classe ʻObject` a également diverses utilisations. Je ne peux pas le recommander car il semble délicat, mais je l'utilise depuis que je savais que je pouvais l'écrire comme ça.

Recommended Posts

Créez une classe temporaire avec le nouvel Object () {}
[Rails6] Créer une nouvelle application avec Rails [Débutant]
[Rails 5] Créer une nouvelle application avec Rails [Débutant]
[Android] Créez une nouvelle classe en héritant d'ImageView
[Rails] rails nouveau pour créer une base de données avec PostgreSQL
Créez un terrain de jeu avec Xcode 12
Mappage à une classe avec un objet de valeur dans How to My Batis
Créer une classe immuable avec JAVA
Créez un environnement Vue3 avec Docker!
Créer une nouvelle application avec Rails
Créez des exceptions avec une interface fluide
Je ne peux pas créer une classe Java avec un nom spécifique dans IntelliJ
Créons vous-même une instance avec .new. .. ..
Créez un fichier jar avec la commande
Créez une application Web simple avec Dropwizard
[Retrait des rails] Créez une fonction de retrait simple avec des rails
[Memo] Créez facilement un environnement CentOS 8 avec Docker
Créez une application de recherche simple avec Spring Boot
Créer un CSR avec des informations étendues en Java
Créez un tableau d'affichage simple avec Java + MySQL
[Windows] [IntelliJ] [Java] [Tomcat] Créer un environnement pour Tomcat 9 avec IntelliJ
Créons un processus chronométré avec la minuterie de Java! !!
[Rails] rails nouveau pour créer une base de données avec PostgreSQL
[Java] Créer une collection avec un seul élément
Comment créer une classe qui hérite des informations de classe
Créez une discussion d'équipe avec Rails Action Cable
Créer un compte SandBox avec IP Fastlane Spaces
Créer une carte multi-touches avec une bibliothèque standard
[Java] Classe d'objets
Créer un serveur API Web avec Spring Boot
Créer un environnement de développement Spring Boot avec docker
Créer un site EC avec Rails 5 ⑨ ~ Créer une fonction de panier ~
Comment supprimer un objet new_record construit avec Rails
Créez un modèle pour le widget iOS14 avec la configuration d'intention.
Créez une application de chat avec WebSocket (Tyrus) + libGDX + Kotlin
S'il y a une transition d'état, créons une classe State
[Apprentissage automatique] J'ai essayé la détection d'objets avec Create ML [détection d'objets]
[Note] Créez un environnement Java à partir de zéro avec docker
Créer un service avec un modèle vide Liferay 7.0 / DXP
Créez un site de démonstration simple avec Spring Security avec Spring Boot 2.1
Un mémo qui gère une classe créée indépendamment avec ArrayList
[Java] Comment rompre une ligne avec StringBuilder
Essayez de créer avec Trailblazer
[Java] Créer un filtre
Un nouvel employé a tenté de créer une fonction d'authentification / autorisation à partir de zéro avec Spring Security
J'ai essayé de créer un environnement de développement java8 avec Chocolatey
Tutoriel pour créer un blog avec Rails pour les débutants Partie 1
Créer un contrôle de page qui peut être utilisé avec RecyclerView
Créez une image Docker avec le JDK Oracle installé (miam
[Rails] J'ai essayé de créer une mini application avec FullCalendar
Créez une application Web Hello World avec Spring Framework + Jetty
Créer un SlackBot avec AWS lambda et API Gateway en Java
Une série d'étapes pour créer des livrables pour les portefeuilles avec Rails
Comment déplacer une autre classe avec une action de bouton d'une autre classe.
Jusqu'à ce que vous créiez une application Web avec Servlet / JSP (Partie 1)
Tutoriel pour créer un blog avec Rails pour les débutants Partie 2