A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

java程序中测试两个变量是否相等有两种方式,一种是利用==运算符,一种是利用equals()方法。

(1)“==”
==是判断的意思,对于局部变量的基本类型(byte,short,int,long,float,double,char,boolean)存储在栈之中,比较的是值,只要值相等,就返回True

int i=0;
double x=0.00;
System.out.println(i==x); // true

而对于引用类型来说,它比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。

        String i=new String("x");
        String n=new String("x");

        System.out.println(i==n); // false

在举个例子,对于在常量池的变量来说,又有新情况

                String s3="hello";
        String s4="hello";

        System.out.println(s3==s4); // true

这是因为hello已经在常量池中了,s4只是重新指向了它,并没有新建一个对象,所以也就没有对象地址不同的情况了

(2)“equals”
其用于比较对象的地址,所以其对引用类型的比较和==的作用相同

源码
基础版
  public boolean equals(Object obj) {
        return (this == obj);
    }

分析:从源码可以看出,一般情况下,equals和==是等价的

一般引用的equals
对于Integer、Boolean等封装类来说,重写了equals

源码如下
(注: instaninstanceof是指,前面的对象是否是后面类的引用)

public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

public boolean equals(Object obj) {
        if (obj instanceof Boolean) {
            return value == ((Boolean)obj).booleanValue();
        }
        return false;
    }

分析:虽然增加了一个判断,但实质上仍然是==的比较

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 != v2)
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

分析:这个代码的意思是,如果两个对象==成立,那么就返回true,如果对象中有String,那么就会一个字符一个字符的比较,判断字符串中每个字符是否相同。

equals扩展
对于equals,jdk给出了一些解释

equals方法在非空对象引用上实现等价关系:

自反性 :对于任何非空的参考值x , x.equals(x)应该返回true 。
它是对称的 :对于任何非空引用值x和y , x.equals(y)应该返回true当且仅当y.equals(x)回报true 。
传递性 :对于任何非空引用值x , y和z ,如果x.equals(y)回报true个y.equals(z)回报true ,然后x.equals(z)应该返回true 。
它是一致的 :对于任何非空引用值x和y ,多次调用x.equals(y)始终返回true或始终返回false ,没有设置中使用的信息equals比较上的对象被修改。
对于任何非空的参考值x , x.equals(null)应该返回false 。
还有需要注意的:
该equals类方法Object实现对象上差别可能性最大的相等关系; 也就是说,对于任何非空的参考值x和y ,当且仅当x和y引用相同的对象( x == y具有值true )时,该方法返回true 。

请注意,无论何时覆盖该方法,通常需要覆盖hashCode方法,以便维护hashCode方法的通用合同,该方法规定相等的对象必须具有相等的哈希码。

equals和hashcode
equals相等就一定有一样的hashcode,hashcode一样,equals不一定返回true

简单解释hashcode

对于JVM虚拟机来说,在堆中有很多很多的对象,那么如何去寻找他们,难道从头遍历吗?JVM选择使用一张表来记录各个对象的位置,一般由哈希编码来记录,每个哈希编码是独一无二的,可以根据哈希编码找到对象地址(也有极少数特殊情况暂不赘述)
hashcode方法在object中定义

public native int hashCode();

native 关键字也就说明了这个方法的底层不由Java来实现,该方法会返回object的整型数字

hashcode能大大降低对象比较次数,提高查找效率!

解释: equals相等就一定有一样的hashcode,hashcode一样,equals不一定返回true

如果两个Java对象A和B,A和B相等(eqauls结果为true),但A和B的哈希码不同,则A和B存入HashMap时的哈希码计算得到的HashMap内部数组位置索引可能不同,那么A和B很有可能允许同时存入HashMap,显然相等/相同的元素是不允许同时存入HashMap,HashMap不允许存放重复元素。

假如两个Java对象A和B,A和B不相等(eqauls结果为false),但A和B的哈希码相等,将A和B都存入HashMap时会发生哈希冲突,也就是A和B存放在HashMap内部数组的位置索引相同这时HashMap会在该位置建立一个链接表,将A和B串起来放在该位置,显然,该情况不违反HashMap的使用原则,是允许的。
————————————————

原文链接:「渐暖°」https://blog.csdn.net/yujing1314/article/details/105898947

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马