[Note] Java: est-il nécessaire de remplacer les égaux pour le jugement d'égalité?

introduction

Comme mentionné dans l 'article précédent, le livre de référence actuel (Introduction à Java qui peut être clairement compris / dp / B00O0NIW30 / ref = dp-kindle-redirect? _ Encoding = UTF8 & btkr = 1)) Je réétudie Java. (En fait, je l'ai déjà lu: blush :)

Dans le livre de référence ci-dessus, lors de la création d'une classe, il est recommandé de ne pas remplacer la méthode déjà fournie et de provoquer un problème involontaire. Un exemple est la méthode ʻequals`.

La méthode ʻequals est une méthode qui détermine si oui ou non elles sont équivalentes plutôt qu'égales. Cependant, selon le livre de référence, la méthode ʻequals de la classe Object fournie à l'origine détermine si elle est équivalente ou non selon qu'elle est égale ou non. Donc, si l'objet qui a appelé ʻequals et l'objet que vous passez comme argument à equals sont égaux, alors les deux objets sont équivalents, non? C'est une traduction qui juge l'évidence comme «.

la mise en oeuvre

Voir le code ci-dessous pour prendre en charge la méthode de décision ci-dessus: lunettes de soleil: Après avoir créé une instance de la classe Person, ajoutez-la à ʻArrayList` et spécifiez la cible de suppression avec une nouvelle instance qui a des membres équivalents aux membres de l'instance ajoutée.

instance.java


import java.util.ArrayList;
import java.util.List;

class Person {
    public String name;
    Person(String name){
        this.name = name;
    }
}
public class instance {
    public static void main(String[] args) {
        List<Person> personList = new ArrayList<Person>();
        personList.add(new Person("Taro"));
        System.out.println("Après l'addition(person) : " + personList.size());
        personList.remove(new Person("Taro"));
        System.out.println("Après suppression(person) : " + personList.size());
    }
}

À première vue, cela semble fonctionner, mais le résultat est que les éléments de ʻArrayList` ne sont pas supprimés.

résultat.java


Après l'addition(person) : 1
Après suppression(person) : 1

Il est vrai que les membres de l'instance ont une relation équivalente, mais si l'adresse mémoire de l'instance est différente, l'adresse mémoire du membre doit être différente, il est donc jugé qu'ils ne sont pas équivalents car ils ne sont pas égaux. Par conséquent, il semble que la méthode ʻequals` de la classe d'objets d'origine soit jugée comme "false".

Par conséquent, comme mentionné au début, nous remplacerons la méthode ʻequals` pour résoudre le problème ci-dessus.

instance.java


class Man {
    public String name;
    Man(String name){
        this.name = name;
    }
    public boolean equals(Object o){
        if(o == this) return true;
        if(o == null) return false;
        if(!(o instanceof Man)) return false;
        Man man = (Man) o ;
        if(!(this.name.equals(man.name))) return false;
        return true;
    }
}
public class instance {
    public static void main(String[] args) {
        List<Man> manList = new ArrayList<Man>();
        manList.add(new Man("Taro"));
        System.out.println("Après l'addition(man) : " + manList.size());
        manList.remove(new Man("Taro"));
        System.out.println("Après suppression(man) : " + manList.size());
    }
}

Cette fois, la méthode ʻequals est prédéfinie dans la classe Man`. Plus précisément, si le type de la source de comparaison et l'objet à comparer sont identiques et que les membres («nom») sont équivalents, «true» est renvoyé.

résultat.java


Après l'addition(man) : 1
Après suppression(man) : 0

Oui, cela fonctionne maintenant comme prévu, comme décrit ci-dessus.

Cependant, remplacer chacun d'entre eux comme décrit ci-dessus est également assez gênant. N'est-il pas suffisant de supprimer l'élément concerné en le tournant avec for comme indiqué ci-dessous sans le remplacer séparément? Penser: penser:

instancce.java


import java.util.ArrayList;
import java.util.List;

class Person {
    public String name;
    Person(String name){
        this.name = name;
    }
}
public class instance {
    public static void main(String[] args) {
        List<Person> personList = new ArrayList<Person>();
        personList.add(new Person("Taro"));

        System.out.println("avant de supprimer l'instruction for(person) : " + personList.size());
        for(int i=0; i<personList.size(); i++){
            Person person = personList.get(i);
            String name = person.name;
            if(name.equals("Taro")){
                personList.remove(person);
            }
        }
        System.out.println("après avoir supprimé l'instruction for(person) : " + personList.size());
    }
}

résultat.java


avant de supprimer l'instruction for(person) : 1
après avoir supprimé l'instruction for(person) : 0

Après cela, pour ceux qui disent que la description de la méthode ʻequals est redondante et qu'il est gênant de l'écrire un par un, si vous utilisez ʻEqualsBuilder de la bibliothèque appelée commons-lang, si tous les membres sont équivalents, l'instance est également considérée comme équivalente. Cela rendra un jugement. Je ne l'ai pas essayé cette fois, mais la méthode de description est la suivante.

equalsBuilder.java


import org.apache.commons.lang3.builder.*;

class Man {
    public String name;
    Man(String name){
        this.name = name;
    }
    public boolean equals(Object o){
        return EqualsBuilder.reflectionEquals(this,o);
    }
}

prime

Cette fois, j'ai posté la méthode de spécification d'un élément avec le for statement et de le supprimer, mais lorsque cela est activé avec le extended for statement, une erreur appelée ConcurrentModificationException se produit. Cette erreur est retournée lorsque la collection à créer est manipulée par ʻadd, remove, etc. quand ʻiterator est créé.

Pour plus de détails, reportez-vous aux liens ci-dessous. .. .. (C'est compliqué à écrire ...) https://qiita.com/sig_Left/items/eebea3f88a16dcfa2983 https://teratail.com/questions/16901

Recommended Posts

[Note] Java: est-il nécessaire de remplacer les égaux pour le jugement d'égalité?
Points à connaître avec Java Equals
[Java] Est-il inutile de vérifier "l'identité" dans l'implémentation de la méthode equals ()?
[Java] Notez le cas où égal est faux mais == est ture.
Est-il possible de générer automatiquement Getter / Setter avec l'interface Java?
[Pour les débutants] On dit que le rubis est rubis, mais qu'en est-il?
Choses à noter pour les nouveaux arrivants d'écrire du code lisible pendant le développement Java
Lors de l'appel de sshpass depuis Java avec shell etc., il semble qu'il soit nécessaire d'avoir un chemin.
[Java] Points à noter avec Arrays.asList ()
Comment utiliser l'égalité et l'égalité (comment utiliser l'égalité)
Ma note de profit: Présentation de Java à Ubuntu
[Java] De nos jours, l'instruction for étendue n'est pas exclusivement pour List, n'est-ce pas?
[Java] Je veux faciliter les choses car il est difficile d'entrer System.out.println