zoukankan      html  css  js  c++  java
  • java中 == 和equals的使用与区别

    java 的数据类型分为“基本数据类型” 和“引用数据类型”:
       ---》在基本数据类型的比较中,== 比的就是基本数据类型变量中所保存的值。

       ---》在引用数据类型的比较中,== 才比较的是变量所指向的对象的地址。

    hashCode()返回该对象的哈希码值,该值通常是一个由该对象的内部地址转换而来的整数,它的实现主要是为了提高哈希表。

    我们以引用数据类型为例,因为基本类型比较的是值,简单无须多言。

    封装好的String 类型为例:

       (注意:ObjectL中有方法equals, hashcode() ,所有其他类都会继承这两个方法)。

    public class hei {
    
        public static void main(String[] args) {
    
            String n1 = "sd";  //常量池字符串sd
            String n2 = "sd";   //常量池字符串sd
            String n3 = new String("sd");   //新对象sd
            String n4 = new String("sd");   //另一个对象sd
            System.out.println(n1.hashCode());
            System.out.println(n2.hashCode());
            System.out.println(n3.hashCode());
            System.out.print("n1与N2 是否相==");
            System.out.println(n1 == n2);
            System.out.print("N1 N2 EQUALS 比较: ");
            System.out.println(n1.equals(n2));
            System.out.print("n2与N3 是否相==");
            System.out.println(n2 == n3);
            System.out.print("N2 N3 EQUALS比较");
            System.out.println(n2.equals(n3));
            System.out.print("N3 N4 EQUALS比较");
            System.out.println(n3.equals(n4));
            
            /*
             * ==操作比较的是两个变量的值是否相等, 对于引用型变量表示的是两个变量在堆中存储的地址是否相同, 即栈中的内容是否相同。
             * equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
             */
        }
    
    }

    这个测试例子中,有N1到N4 4个字符串:

    (1)首先看N1与N2 这两个都是直接量,也就是N1放入“sd”在常量池中,常量池中有了一个对象"sd", 

      当 String n2 = "sd"; 执行的时候, 系统会查找常量池,找到了"sd",就把N2指向常量池的对象“sd”中,实际上N1 N2指向的是同一个对象。(所以地址相同,对象也相同,当然内容也相同了)。


    (2) N3 N4是通过NEW创建的对象,所以不会在常量池中,而是新建一个对象。所以N3 N4 指向的地址不同,这里必须知道的是,
    N3 N4 存放于内存的栈中,N3 N4 的内容分别是堆中对象的地址,是不同的。
    所以N3 == N4 是false ,因为== 比较的是内存地址
    同理 N2 == N3 也是false。
    N3.equals(N4) 是true ,因为String重写了equals()方法,如下:
    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;
    }
    

      从中我们可以看出,String 类重写了equals方法使其比较了字符串内容。  而Object中的equals方法比较的是地址。

    如下:  Oject中的equals() 

    public boolean equals(Object obj) {
    return (this == obj);
    }

    至于hashcode() ,这个整型值是用在集合框架中的,目的就是快速搜索。  --摘自网络

      由于集合set要求元素不重复,所以每次插入的时候需要进行确认有没有重复,如果元素有1万个,需要1万次的equals那么效率很慢很慢。
    
      hashCode方法实 际上返回的就是与对象内存地址有关的一个数值。
      这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以 直接存储在这个位置  上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。所以这里存在一个冲突解    决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。
      所以,Java对于eqauls方法和hashCode方法是这样规定的:
    1、如果两个对象相同,那么它们的hashCode值一定要相同;
    2、如果两个对象的hashCode相同,它们并不一定相同
      上面说的对象相同指的是用eqauls方法比较。



  • 相关阅读:
    给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
    11
    实战 迁移学习 VGG19、ResNet50、InceptionV3 实践 猫狗大战 问题
    tx2系统备份与恢复
    如何在Ubuntu 18.04上安装和卸载TeamViewer
    bzoj 3732 Network (kruskal重构树)
    bzoj2152 聪聪可可 (树形dp)
    牛客 216D 消消乐 (二分图最小点覆盖)
    牛客 197E 01串
    Wannafly挑战赛23
  • 原文地址:https://www.cnblogs.com/xiancai5210/p/3858703.html
Copyright © 2011-2022 走看看