java中 ==、equals 、HashCode、 笔记

1.java中的 ==

  • 对于基本数据类型 byte,short,char,int,long,float,double,boolean
    他们之间的比较,应用双等号(==),比较的是他们的值。

  • 对于抽象数据类型(如 对象),== 比较的是两个实例的 地址

    2.equals()方法:

  • Object类中的equals方法的源码:

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

可见,Object类的equals方法就是利用==进行比较

  • 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方法:
1.首先比较两个String实例的地址
2.当地址不同时,判断两个实例是否为String类型,然后比较字符串的值

  1. Integer类对equals的重写:

源码:

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


    /**
     * Returns the value of this {@code Integer} as an
     * {@code int}.
     */
    public int intValue() {
        return value;
    }

**我们可以通过重写equals(Object obj)方法来实现自定义的比较规则,
但在重写equals(Object obj)时,要考虑同时重写hashCode()方法**


3.hashCode()

官方API对hashCode()的解释 :

Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by HashMap.

The general contract of hashCode is:
A . Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in 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.
B . If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
C .It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the 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.

  • Object 类的hashCode() :
/**Object类的hashCode()是一个native方法
*默认情况下,Object中的hashCode() 返回对象的32位jvm内存地址。也就是说*如果对象不重写该方法,则返回相应对象的32为JVM内存地址。
*/
public native int hashCode();
  • 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源码中使用private final char value[];保存字符串内容,因此String是不可变的。

总结:
(1)当equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

(2)Hashtable实现一个哈希表,为了成功地在哈希表中存储和检索对象,用作键的对象必须实现 hashCode 方法和 equals 方法。同(1),必须保证equals相等的对象,hashCode 也相等。因为哈希表通过hashCode检索对象。

(3)instanceof运算符:
obj1 instanceof obj2
当instanceof左侧的引用类型变量所引用对象的实际类型是右侧给出的类型、或其子类类型时,整个表达式为true

(4)String的字符串缓冲池

测试代码:   
        String str1 = "hello world";
        String str2 = "hello world";
        String str3 = new String("hello world");
        System.out.println(str1==str2);
        System.out.println(str1==str3);
        System.out.println(str1.equals(str3));
        System.out.println(str1.hashCode()+"  "+
                            str2.hashCode()+"  "+
                            str3.hashCode());

console结果:

true
false
true
1794106052  1794106052  1794106052

分析:

java程序在运行的时候会创建一个字符串缓冲池,当String str1 = “hello world”;创建String实例时,程序首先会在这个String缓冲池中寻找相同值的对象,若存在,则将实例付给引用,不存在时,则创建实例并将新建的实例放入缓冲池,所以str2与str1引用同一个实例

但当使用了 new 操作符,他明白的告诉程序:”我要一个新的!不要旧的!”于是一个新的值为”hello world”的 Sting对象被创建在内存中。
所以str3==str1返回false(因为是不同的实例)

String类对hashCode()、equals()进行了重写,所以str1、str2、str3三者的hashCode值相同,equals也返回true

参考:
http://docs.oracle.com/javase/8/docs/api/
http://www.cnblogs.com/zhxhdean/archive/2011/03/25/1995431.html
http://www.cnblogs.com/xudong-bupt/p/3960177.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值