面试收集录

java中==、equals、hashCode的联系与区别

2018-08-02  本文已影响16人  凯玲之恋

1 概述

这三者怎么联系起来的,有交叉--。

2 ==关系运算符

2.1 JAVA的运算符

==是关系运算符

2.2 Java中的数据类型在内存的存储原理

2.3 基本类型转换

2.3.1 自动类型提升(隐式转换),小数据类型向大数据类型转换.

2.3.2 强制类型转换:想让大数据类型其转换成小数据类型.

2.2 关系运算符

关系运算符用于比较两个数值之间的大小,其运算结果为一个逻辑类型(boolean布尔类型)的数值。
==关系运算符

3 equals和hashcode的区别和联系

3.1 JDK对equals(Object obj)和hashcode()这两个方法的定义和规范

3.1.1 定义

3.1.2 关于这两个方法的重要规范

只是抽取了最重要的两个

3.2 equals

3.2.1 Object类的equals

Object类中的equals方法和“==”是一样的

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

3.2.1 Integer的equals

    @Override
    public boolean equals(Object o) {
        return (o instanceof Integer) && (((Integer) o).value == value);
    }

3.2.2 String类的equals

    @Override public boolean equals(Object other) {
        if (other == this) {
          return true;
        }
        if (other instanceof String) {
            String s = (String)other;
            int count = this.count;
            if (s.count != count) {
                return false;
            }

            if (hashCode() != s.hashCode()) {
                return false;
            }
            for (int i = 0; i < count; ++i) {
                if (charAt(i) != s.charAt(i)) {
                    return false;
                }
            }
            return true;
        } else {
            return false;
        }
    }

String类,Integer类等等一些类,是重写了equals方法,才使得equals和“==不同”,所以,当自己创建类时,自动继承了Object的equals方法,要想实现不同的等于比较,必须重写equals方法。

3.2.3 自己实现equals坚持一般的规范

当你重写equals方法时,必须遵守它的通用约定。

3.2.4 重写配方

  1. 使用= =运算符检查参数是否为该对象的引用。如果是,返回true。这只是一种性能优化,但是如果这种比较可能很昂贵的话,那就值得去做。
  2. 使用instanceof运算符来检查参数是否具有正确的类型。 如果不是,则返回false。
  3. 参数转换为正确的类型。因为转换操作在instanceof中已经处理过,所以它肯定会成功
  4. 对于类中的每个“重要”的属性,请检查该参数属性是否与该对象对应的属性相匹配。如果所有这些测试成功,返回true,否则返回false。如果步骤2中的类型是一个接口,那么必须通过接口方法访问参数的属性;如果类型是类,则可以直接访问属性,这取决于属性的访问权限。

3.2.5 示例

public final class PhoneNumber {

    private final short areaCode, prefix, lineNum;

    public PhoneNumber(int areaCode, int prefix, int lineNum) {
        this.areaCode = rangeCheck(areaCode, 999, "area code");
        this.prefix = rangeCheck(prefix, 999, "prefix");
        this.lineNum = rangeCheck(lineNum, 9999, "line num");
    }

    private static short rangeCheck(int val, int max, String arg) {
        if (val < 0 || val > max)
            throw new IllegalArgumentException(arg + ": " + val);
        
        return (short) val;
    }

    @Override
    public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof PhoneNumber))
            return false;

        PhoneNumber pn = (PhoneNumber) o;

        return pn.lineNum == lineNum && pn.prefix == prefix
                && pn.areaCode == areaCode;
    }

    ... // Remainder omitted
}

以下是一些最后提醒:

4 hashCode

4.1 hashCode方法的描述

返回该对象的哈希码值。支持此方法是为了提高哈希表(例如java.util.Hashtable提供的哈希表)的性能。

4.2 hashCode的常规协定

4.3 java中数据结构hash和equals的使用

java原生数据结构源码待看。看完补充。

参考

Java 基本数据类型 及 == 与 equals 方法的区别
java中hashcode和equals的区别和联系
Effective Java 第三版——10. 重写equals方法时遵守通用约定

上一篇 下一篇

猜你喜欢

热点阅读