结合源码分析==与equals与hashCode

.equals()与==

equals是所有类都具有的方法,注意基本八种数据类型是不具备equals方法的,只有他们对应的包装类才具备。

//Character    
    public boolean equals(Object obj) {
        if (obj instanceof Character) {
            return value == ((Character)obj).charValue();
        }
        return false;
    }
//Byte
    public boolean equals(Object obj) {
        if (obj instanceof Byte) {
            return value == ((Byte)obj).byteValue();
        }
        return false;
    }
//Short
    public boolean equals(Object obj) {
        if (obj instanceof Short) {
            return value == ((Short)obj).shortValue();
        }
        return false;
    }
//Integer
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
//Long
    public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
    }
//Float
    public boolean equals(Object obj) {
        return (obj instanceof Float)
               && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
    }
//Double
    public boolean equals(Object obj) {
        return (obj instanceof Double)
               && (doubleToLongBits(((Double)obj).value) ==
                      doubleToLongBits(value));
    }
//Boolean
    public boolean equals(Object obj) {
        if (obj instanceof Boolean) {
            return value == ((Boolean)obj).booleanValue();
        }
        return false;
    }

可以看到基本上都是先判断被equals的对象是不是同一个类型,如果不是则直接返回false。

如果是同一个类型则直接进行类似于.value()的方法,获取这个value。进一步查看源码可以发现最后这个方法的返回值都是基本数据类型。

String对象的具体实现的源码如下:

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

除了上述类型之外,我们来看看普通的类如果没有重写.equals()方法,那他的底层实现是什么样:

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

我们可以看到无论如何包装类也好,String也好,还是任何没有重写.equals的类也好,都进行了==的比较,如果两个对象==那么久说明为true,如果不等则返回false。那么关于==的问题呢?什么情况下==等于true呢?

下面先写几行代码,猜一猜最后的结果。

int 类型:

		Integer a1 = new Integer(1111);
		Integer c1 = new Integer(1111);
		System.out.println(c1==a1);
		System.out.println(c1.equals(a1));
	
		Integer a2 = new Integer(22);
		Integer c2 = new Integer(22);
		System.out.println(c2==a2);
		System.out.println(c2.equals(a2));
		
		int a3 = 3333;
		Integer c3 = new Integer(3333);
		System.out.println(c3==a3);
		System.out.println(c3.equals(a3));
//		System.out.println(a3.equals(c3));
		
		int a4 = 4444;
		int c4 = 4444;
		System.out.println(c4==a4);
//		System.out.println(c4.equals(a4));

下面大家思考一下结果是什么:

false
true
false
true
true
true
true

至于Integer和int比较为什么为True,请了解一下自动拆箱。

String 类型:

		String a1 = "1111";
		String c1 = "1111";
		System.out.println(c1==a1);
		
		String a2 = new String("2222");
		String c2 = new String("2222");
		System.out.println(c2==a2);
		
		String a3 = "3333";
		String c3 = new String("3333");
		System.out.println(c2==a2);

答案:

true
false
false

通过上述的分析可以得出如下结论:

1、基本数据类型不存在.equals方法

2、基本数据类型的==比较的是数值是否相等。

3、基本数据类型包装类的==比较的是对象是否是相同的,也就是地址。new出来的东西就是不同的。

4、基本数据类型包装类的.equals()方法比较的是值。

5、String类型的.equals()方法首先会比较是不是相同的对象,其次如果不是相同的对象会比较对象中的每一个字符是不是一样的

6、String类型和其他Object类型的== 都是比较对象的地址,也就是是否是同一个对象。

7、如果没有重写equals方法 那么默认对象相同equals为true

 

hashCode与==

下面我们看看hashCode方法与==方法的差异

		System.out.println("==================");
		Integer a1 = new Integer(1111);
		Integer c1 = new Integer(1111);
		System.out.println(c1==a1);
		System.out.println(a1.hashCode());
		System.out.println(c1.hashCode());
		System.out.println("==================");
		Integer a2 = new Integer(22);
		Integer c2 = new Integer(22);
		System.out.println(c2==a2);
		System.out.println(a2.hashCode());
		System.out.println(c2.hashCode());
		System.out.println("==================");
		int a3 = 3333;
		Integer c3 = new Integer(3333);
		System.out.println(c3==a3);
		System.out.println(c3.hashCode());
//		System.out.println(a3.hashCode());
		System.out.println("==================");
		Byte a4 = new Byte((byte) 1);
		Byte c4 = new Byte((byte) 1);
		System.out.println(c4==a4);
		System.out.println(a4.hashCode());
		System.out.println(c4.hashCode());
		System.out.println("==================");
		Long a5 = new Long(1);
		Long c5 = new Long(1);
		System.out.println(c5==a5);
		System.out.println(a5.hashCode());
		System.out.println(c5.hashCode());
		System.out.println("==================");
		String a6 = new String("123");
		String c6 = new String("123");
		System.out.println(c6==a6);
		System.out.println(a6.hashCode());
		System.out.println(c6.hashCode());
		System.out.println("==================");
		JDKProxyForUser jpu1 = new JDKProxyForUser();
		JDKProxyForUser jpu2 = new JDKProxyForUser();
		System.out.println(jpu1==jpu2);
		System.out.println(jpu1.hashCode());
		System.out.println(jpu2.hashCode());
==================
false
1111
1111
==================
false
22
22
==================
true
3333
==================
false
1
1
==================
false
1
1
==================
false
48690
48690
==================
false
1252169911
2101973421

下面我们查看Byte类型的HashCode源码(其余基本类型包装类基本如此)

    /**
     * Returns a hash code for this {@code Byte}; equal to the result
     * of invoking {@code intValue()}.
     *
     * @return a hash code value for this {@code Byte}
     */
    @Override
    public int hashCode() {
        return Byte.hashCode(value);
    }

    /**
     * Returns a hash code for a {@code byte} value; compatible with
     * {@code Byte.hashCode()}.
     *
     * @param value the value to hash
     * @return a hash code value for a {@code byte} value.
     * @since 1.8
     */
    public static int hashCode(byte value) {
        return (int)value;
    }

下面我们再查看其他类型hashCode源码

/**
     * Returns a hash code value for the object. This method is
     * supported for the benefit of hash tables such as those provided by
     * {@link java.util.HashMap}.
     * <p>
     * The general contract of {@code hashCode} is:
     * <ul>
     * <li>Whenever it is invoked on the same object more than once during
     *     an execution of a Java application, the {@code hashCode} method
     *     must consistently return the same integer, provided no information
     *     used in {@code equals} comparisons on the object is modified.
     *     This integer need not remain consistent from one execution of an
     *     application to another execution of the same application.
     * <li>If two objects are equal according to the {@code equals(Object)}
     *     method, then calling the {@code hashCode} method on each of
     *     the two objects must produce the same integer result.
     * <li>It is <em>not</em> required that if two objects are unequal
     *     according to the {@link java.lang.Object#equals(java.lang.Object)}
     *     method, then calling the {@code hashCode} method on each of the
     *     two objects must produce distinct integer results.  However, the
     *     programmer should be aware that producing distinct integer results
     *     for unequal objects may improve the performance of hash tables.
     * </ul>
     * <p>
     * As much as is reasonably practical, the hashCode method defined by
     * class {@code Object} does return distinct integers for distinct
     * objects. (This is typically implemented by converting the internal
     * address of the object into an integer, but this implementation
     * technique is not required by the
     * Java&trade; programming language.)
     *
     * @return  a hash code value for this object.
     * @see     java.lang.Object#equals(java.lang.Object)
     * @see     java.lang.System#identityHashCode
     */
    public native int hashCode();

可以得出结论:

1、基本数据类型没有hashCode()方法。

2、基本数据类型的包装类的hashCode为包装类的基本类型的值。

3、hashCode相同并不代表==等于true,也就是并不是同一个对象。

4、hashCode不同则肯定不是同一个对象。

5、两个对象equals则hashCode一定相同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值