Maison > Java > javaDidacticiel > le corps du texte

Que sont égaux et == en Java ? Quelles sont les différences ?

青灯夜游
Libérer: 2018-10-19 17:13:22
avant
3776 Les gens l'ont consulté

Le contenu de cet article est de présenter ce que sont égaux et == en Java ? Quelles sont les différences ? Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il vous sera utile.

1. Types de données en Java et signification de "==" :

  • Types de données de base (également appelés types de données primitifs) : byte, short, char, int, long, float, double, boolean. Pour les comparer, utilisez le double signe égal (==), et compare leurs valeurs .

  • Type de données de référence : Lorsqu'elles sont comparées à l'aide de (==), elles sont comparées L'adresse de stockage en mémoire (pour être précis, il s'agit de mémoire de tas adresse ).

Remarque : Pour le deuxième type, à moins qu'il ne s'agisse du même nouvel objet, le résultat de leur comparaison est vrai, sinon le résultat de la comparaison est faux. Car à chaque nouvelle fois, l'espace mémoire du tas sera rouvert.

2. Introduction à la méthode equals() :

Toutes les classes en JAVA héritent de la super classe Object Dans la classe Object An. La méthode equals est définie dans. Le code source de equals s'écrit comme ceci :

public boolean equals(Object obj) {
    //this - s1
    //obj - s2
    return (this == obj);
}
Copier après la connexion

Comme vous pouvez le voir, le comportement initial par défaut de cette méthode est de comparer la valeur de l'adresse mémoire de l'objet de manière générale. , cela n'a que peu d'importance. Par conséquent, cette méthode a été remplacée dans certaines bibliothèques de classes, telles que String, Integer et Date. Parmi ces classes, equals a sa propre implémentation (généralement utilisée pour comparer si les valeurs des variables membres des objets sont les mêmes), au lieu de comparer l'adresse de stockage de la classe dans la mémoire tas.

Donc, pour une comparaison égale entre les types de données composites, sans remplacer la méthode égale, la comparaison entre eux est toujours la valeur d'adresse de l'emplacement de stockage dans la mémoire. comme double signe égal (==) ; s'il est écrasé, suivez les exigences d'écrasement.

Résumons les deux paragraphes ci-dessus :

== Fonction :
Type de base : Ce qui est comparé est de savoir si le les valeurs sont les mêmes
Type de référence : ce qui est comparé est de savoir si la valeur de l'adresse est la même

Le rôle des égaux :
Référence type : Par défaut, ce qui est comparé est la valeur de l'adresse.

Remarque : Nous pouvons toutefois remplacer nous-mêmes cette méthode en fonction de la situation. Généralement, la réécriture est générée automatiquement et les valeurs des variables membres des objets de comparaison sont les mêmes

3. La méthode equals() de la classe String :

Prenons maintenant la classe String comme exemple :

Nous allons dans le répertoire srcjavalang pour trouver la classe String et constatons que la méthode equals a été réécrite comme suit :

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
Copier après la connexion

Comme le montre le code ci-dessus, la classe String est La méthode overriddene equals() compare en fait le contenu de deux chaînes. Jetons un coup d'œil à la comparaison des classes String à travers le code réel.

1. L'exemple de code est le suivant :

public class StringDemo {
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = "Hello";
        System.out.println(s1 == s2);   // true
    }
}
Copier après la connexion

Dans le code ci-dessus, utilisez "==" pour comparer s1 et s2, et le résultat renvoyé est vrai.

2. Si vous modifiez légèrement le programme, vous trouverez quelque chose d'étrange :

public class StringDemo {
    public static void main(String args[]) {
        String str1 = "Hello";
        String str2 = new String("Hello");
        String str3 = str2; // 引用传递
        System.out.println(str1 == str2); // false
        System.out.println(str1 == str3); // false
        System.out.println(str2 == str3); // true
        System.out.println(str1.equals(str2)); // true
        System.out.println(str1.equals(str3)); // true
        System.out.println(str2.equals(str3)); // true
    }
}
Copier après la connexion

Dans la 4ème ligne de code ci-dessus, nous créons un nouvel objet et utilisons "==" pour comparez s1 et s2 , le résultat renvoyé est faux ; et en utilisant "equals" pour comparer s1 et s2, le résultat renvoyé est vrai.

Afin d'analyser le code ci-dessus, nous devons d'abord analyser l'espace mémoire du tas et l'espace mémoire de la pile, c'est très important :

Veuillez expliquer la différence entre "==" et equals() dans la comparaison de chaînes ?

  • == : Ce qui est comparé est de savoir si les valeurs​​de deux adresses de mémoire de chaîne (mémoire tas) sont égales, ce qui est un comparaison numérique ;

  • equals() : compare le contenu de deux chaînes, ce qui est une comparaison de contenu.

À l'avenir, equals() sera utilisé lors des jugements d'égalité de chaînes.

3. Changez à nouveau le programme :

public class ObjectDemo{
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = new String("Hello");
        s2 = s2.intern();
        System.out.println(s1 == s2);       //  true
        System.out.println(s1.equals(s2));  //  true
    }
}
Copier après la connexion

Dans la ligne 5 du code ci-dessus, la méthode intern() "abc".intern de java.lang .String La valeur de retour de la méthode () est toujours la chaîne "abc". En apparence, il semble que cette méthode soit inutile. Mais en fait, il fait une petite action : Vérifie s'il y a une chaîne telle que "abc" dans le pool de chaînes Si elle existe, il renvoie la chaîne dans le pool si elle n'existe pas ; cette méthode "abc" sera ajoutée au pool de chaînes avant que sa référence ne soit renvoyée.

4. Comparez les valeurs de deux objets :

Le code est le suivant :

package com.smyh;

public class ObjectDemo {
    public static void main(String args[]){
        Student student1 = new Student("生命壹号",22,"成都");
        Student student2 = new Student("生命壹号",22,"成都"); 
        System.out.println(student1==student2);
        System.out.println(student1.equals(student2));
    }
}
class Student {
    private String name;
    private int age;
    private String address;
    public Student(String name,int age,String address){
        this.name = name;
        this.age = age;
        this.address = address;
    }
    //重写Object类中的equals方法(比较两个对象的值是否相等)
    public boolean equals(Object obj){
        //为了提高效率:如果两个内存地址相等,那么一定是指向同一个对内存中的对象,就无需比较两个对象的属性值(自己跟自己比,没啥意义嘛)
        if(this==obj){
            return true;
        }
        
        //为了提供程序的健壮性
        //我先判断一下,obj是不是学生的一个对象,如果是,再做向下转型,如果不是,直接返回false。
        //这个时候,我们要判断的是对象是否是某个类的对象?
        //记住一个格式:对象名 instanceof 类名。表示:判断该对象是否是该类的一个对象       
        if(!(obj instanceof Student)){        
            return false;                
        }
        
        //如果是就继续
        Student s = (Student)obj;//强制转换,即向下转型(毕竟Object类型没有具体的对象属性)        
        return this.name.equals(s.name) && this.age == s.age && this.address.equals(s.address);//判断两个对象的属性值是否相等
    }
}
Copier après la connexion

上述代码中,首先判断传递进来的对象与当前对象的地址是否相等,如果相等,则肯定是同一个堆内存中的对象。因为传递进来的参数是Object类型,所以任何对象都可以接收。一旦接收进来,就将Object类型的对象向下转型,然后判断具体的属性值。

 运行效果:

五、equals()的重写规则

前面我们已经知道如何去重写equals方法来实现我们自己的需求了,但是我们在重写equals方法时,还是需要注意如下几点规则的。

  • 自反性。对于任何非null的引用值x,x.equals(x)应返回true。

  • 对称性。对于任何非null的引用值x与y,当且仅当:y.equals(x)返回true时,x.equals(y)才返回true。

  • 传递性。对于任何非null的引用值x、y与z,如果y.equals(x)返回true,y.equals(z)返回true,那么x.equals(z)也应返回true。

  • 一致性。对于任何非null的引用值x与y,假设对象上equals比较中的信息没有被修改,则多次调用x.equals(y)始终返回true或者始终返回false。

  • 对于任何非空引用值x,x.equal(null)应返回false。

六、为什么重写equals()的同时还得重写hashCode()

我们知道equals()和hashCode()是java Object中两个基本方法,有时候由于业务的需求,需要我们重写equals()方法,比如对于Person类中,业务的需要让我们当Person对象的cardID一致的时候,就认为两个对象equals,此时就需要在Person类中重写equals()方法,如下:

public class Person
{

    public String name;
    public int age;
    public String cardID;

    .....// 省略

    @Override
    public boolean equals(Object o)
    {
        if (o instanceof Person)
        {
            Person p = (Person) o;
            return this.cardID.equals(p.cardID);
        } else
        {
            return false;
        }
    }

    @Override
    public int hashCode()
    {
        return this.cardID.hashCode();
    }

    ......// 省略


}
Copier après la connexion

保证相同对象的hashCode一定相同,不同对象的hashCode基本相同。

阅读HashMap的源码,我们可以看到,HashMap中实现了一个Entry[]数组,数组的每个item是一个单项链表的结构,当我们put(key, value)的时候,HashMap首先会newItem.key.hashCode()作为该newItem在Entry[]中存储的下标,要是对应的下标的位置上没有任何item,则直接存储上去,要是已经有oldItem存储在了上面,那就会判断oldItem.key.equals(newItem.key),那么要是我们把上面的Person作为key进行存储的时候,重写了equals()方法,但没重写hashCode()方法,当我们去put()的时候,首先会通过hashCode() 计算下标,由于没有重写hashCode(),那么实质是完整的Object的hashCode(),会受到Object多个属性的影响,本来equals的两个Person对象,反而得到了两个不同的下标。

同样的,HashMap在get(key)的过程中,也是首先调用hashCode()计算item的下标,然后在对应下标的地方找,要是为null,就返回null,要是 != null,会去调用equals()方法,比较key是否一致,只有当key一致的时候,才会返回value,要是我们没有重写hashCode()方法,本来有的item,反而会找不到,返回null结果。

所以,要是你重写了equals()方法,而你的对象可能会放入到散列(HashMap,HashTable或HashSet等)中,那么还必须重写hashCode(), 如果你的对象有可能放到有序队列(实现了Comparable)中,那么还需要重写compareTo()的方法。

总结:以上就是本篇文的全部内容,希望能对大家的学习有所帮助。更多相关教程请访问Java视频教程java开发图文教程bootstrap视频教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:csdn.net
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal