您的位置 首页 java

Java中equals 与 hashCode的分析

1.equals与==的区别

“==”通常比较的是两个对象是不是同一个对象,或同一个内存地址,“equals”通常是比较对象的值是否相等,即使两个对象的内存地址不一样。

在此贴出: String 的equals的实现源码:

 public boolean equals(Object anObject) {
        # 首先使用==判断了当前对象(this)与入参对象(anObject)的内存地址是否一样,如果一样,返回true
        if (this == anObject) {
            return true;
        }
        # 判断入参对象是String类型
        if (anObject  instanceof  String) {
            String anotherString = (String)anObject;
            # 当前对象的字符串长度
            int n = value.length;
            # 开始逐个字符的判断字符串是不是相等的
            if (n == anotherString.value.length) {
                char v1[] = value;  #当前字符串的char数组
                char v2[] = anotherString.value; #入参对象字符串的char数组
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }  

测试equals与==区别,如下代码示例:

 public class AddrTest {
    public  static   void  main(String[] args) {
        String a=new String("a");  #初始化一个新的内存地址
        String b=new String("a"); 	#初始化一个新的内存地址
        String c=b;					#新增了一个变量引用,指向b对象的内存地址
        String d=new String(c);		#初始化一个新的内存地址,并把c的值赋给d的内存地址
        System.out.println(a==b);
        System.out.println(a.equals(b));
        System.out.println(a==c);
        System.out.println(b==c);
        System.out.println(b==d);
    }
}
  

输出结果:

         System.out.println(a==b);  #false 因为a和b在不同的内存地址中
        System.out.println(a.equals(b)); #true  因为a和b的内容是相同的
        System.out.println(a==c);		#false	a和c在不同的内存地址
        System.out.println(b==c);		#true	b和c指向同一个对象,同一个内存地址
        System.out.println(b==d);		#false	b和d在不同的内存地址
  

2. hashCode 的分析

hashCode方法继承自Object对象,每个类可以有重写自己的hashCode方法

例如常用的 HashMap 的hashCode方法的 其中一个实现 如下:

 public  abstract  class AbstractMap<K,V> implements Map<K,V>{

        ...
        
        public int hashCode() {
                int h = 0;
                 Iterator <Entry<K,V>> i = entrySet().iterator();
                while (i.hasNext())
                    h += i.next().hashCode();
                return h;
            }
    
    ...
    
    }  

而String的hashCode方法源码如下:

 public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
             char  val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }  

可以看到String字符串的hashCode,是以

 val[0]*31^(n-1) + val[1]*31^(n-2) + ... + val[n-1] 
  

累加的,基本不会有不同 字符串 有相同hashCode的值的情况,具体分析请参考 Java 编程:String 类中 hashCode() 方法详解

但是:
HashMap的hashCode的会有不同的键值对产生相等的hashCode值的情况:

贴出测试源码:

 public class Test {
    public static void main(String[] args) {
        Map<String,Object> map1=new HashMap<>();
        Map<String,Object> map2=new HashMap<>();
        map1.put("a1",12);
        map1.put("a2",20);

        map2.put("a1",21);
        map2.put("a2",13);

        System.out.println(map1.hashCode());
        System.out.println(map2.hashCode());
    }
}  

输出结果:

 6113
6113  

原因就是: h += i.next().hashCode(); ,无序的累加可能致使相同的结果

文章来源:智云一二三科技

文章标题:Java中equals 与 hashCode的分析

文章地址:https://www.zhihuclub.com/182595.shtml

关于作者: 智云科技

热门文章

网站地图