[Couper constamment, la raison est toujours désordonnée] Ces choses à peu près égales et == en Java

Élaborer sur les égaux et ==

1. Originaire de l'objet

Nous savons tous que toutes les classes de Java héritent par défaut de la superclasse Object et que Object possède plus de méthodes 10. Ici, nous présentons les principales et les toStringméthodes .equalshashcode

  • toStingLa méthode renvoie " " par défaut类名@地址值 ; nous la réécrivons généralement, puis nous pouvons imprimer directement l'objet pour obtenir la forme réécrite de la sortie.

Les faits saillants suivants equalset hashcode:

  • equalsLa méthode compare l'objet (adresse) par défaut, c'est-à-dire que l'opération == est effectuée. Si le contenu doit être comparé, il doit être réécrit.
  • hashcodeLa valeur par défaut est de renvoyer une chaîne d'entiers basée sur l'adresse de l'objet, ce qui signifie que la même adresse hashcodeest la même. Et c'est hashcodeune méthode dans Object, une nativeméthode locale, indiquant que la méthode est implémentée en appelant d'autres langages, ce qui est un peu comme une interface, et vous n'avez pas besoin de l'implémenter vous-même.

Voici le code source pertinent dans la classe Object :

 public String toString() {
    
    
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
public boolean equals(Object obj) {
    
    
        return (this == obj);
    }
public native int hashCode();

2, empêtré dans la ficelle

Parlons des caractéristiques java.lang.Stringde la neutralisation :equalshashcode

String equalset hashcodeles deux sont réécrits.

Tout d'abord, le hashcode calcule le hachage en fonction du contenu de l'objet, donc le contenu de l'objet est le même, et leur hashcode est le même.

public int hashCode() {
    
    
        int h = hash;
        if (h == 0 && value.length > 0) {
    
    
            char val[] = value;
			
            //这种 hash 计算方式不难看出,元素 value 相同 h 会是一样的
            for (int i = 0; i < value.length; i++) {
    
    
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

Pour les chaînes, equals compare le contenu de l'objet, ce qui est également dû à la spécificité des chaînes.

Ensuite == compare l'adresse de l'objet.

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

3. Vérification des codes

Voici le code test :

public class TEST {
    
    
    public static void main(String[] args){
    
    

        Object o1 = new Object();
        Object o2 = new Object();
        Object o3 = o2;
        System.out.println(o1==o2); //false
        System.out.println(o1.equals(o2)); //false,Object 原生 equals,默认比较地址
        System.out.println(o1.hashCode()==o2.hashCode()); //false,根据地址计算 hash
        System.out.println(o2.hashCode()==o3.hashCode()); //true

        String s1 = "abc";
        String s2 = s1; //常量池优化机制
        String s3 = new String("abc");
        System.out.println(s1==s3); //false 地址不一样,一个在常量池中一个在堆中
        System.out.println(s1.equals(s3)); //true,比较内容
        System.out.println(s2.hashCode()==s1.hashCode()); //true,根据内容计算 hash
        System.out.println(s1.hashCode()==s3.hashCode()); //true
    }

}

4. Méthode de remplacement

Dans certains scénarios, nous devons personnaliser la règle "égale". Par exemple, si nous définissons le même contenu de l'objet comme égal, nous devons remplacer la méthode equals :

import java.util.Objects;

public class Person {
    
    	
	private String name;
	private int age;
	
    @Override
    public boolean equals(Object o) {
    
    
        // 如果对象地址一样,则认为相同
        if (this == o)
            return true;
        // 如果参数为空,或者类型信息不一样,则认为不同
        if (o == null || getClass() != o.getClass())
            return false;
        // 转换为当前类型
        Person person = (Person) o;
        // 要求基本类型相等,并且将引用类型交给 java.util.Objects 类的 equals 静态方法取用结果
        return age == person.age && Objects.equals(name, person.name);
    }
}
 //对象比较地址,字符串比较内容
 public static boolean equals(Object a, Object b) {
    
    
 //1,对象类型时
 //a==b 为 true,则 true
 //a==b 为 false,则 false;
 //2,string 类型时
 //地址 true,内容 true,则 true
 //地址 false,内容 true,则 true;地址不等内容不等,flase
        return (a == b) || (a != null && a.equals(b));
    }

Dans certaines occasions, nous devons également réécrire le hashcode. Par exemple, le mécanisme de jugement de "l'égalité des éléments" dans HashSet consiste à considérer de manière exhaustive les méthodes hashcode et equals ; ainsi, lorsque nous personnalisons l'objet, nous devons réécrire le hashcode et equals méthodes.

La réécriture de méthode de equals fait référence à l'exemple ci-dessus. Voici la réécriture de la méthode hashcode et du code source de la méthode correspondante :

@Override 
public int hashCode() {
    
    
     //仍然调用的是 Objects 的 hash 方法
    //对于这里而言,age 走地址判断;name 走内容判断;所以只要他们内容相同就会返回相同的 hash
        return Objects.hash(name, age);
    }
public static int hash(Object... values) {
    
    
        return Arrays.hashCode(values);
    }
public static int hashCode(Object a[]) {
    
    
        if (a == null)
            return 0;

        int result = 1;
		//仍然走的是 Object 的 hashCode 方法
        for (Object element : a)
            result = 31 * result + (element == null ? 0 : element.hashCode());

        return result;
    }

Bien sûr, la méthode de réécriture ci-dessus, la génération d'idées, fournit un modèle de réécriture, qui peut être généré en un clic.

5. Résumé

Le hashcode de Object renvoie la valeur en fonction de l'adresse, equals compare l'adresse, == compare l'adresse ;

Le hashcode de String renvoie la valeur en fonction du contenu, equals compare le contenu, == compare l'adresse.

C'est-à-dire que Object compare toujours l'adresse.Comme String a une réécriture de méthode, c'est le contenu de la comparaison. == est en fait une adresse de comparaison en soi.

Je suppose que tu aimes

Origine blog.csdn.net/qq_40589204/article/details/119394186
conseillé
Classement