zoukankan      html  css  js  c++  java
  • hashCode equals ==

    参考:https://mp.weixin.qq.com/s/aDDotZphhDRCWV4nAZbwhQ

    1 作用

    用来对比两个对象是否相等一致  ①效率 ②可靠性

    2 区别

    因为重写的equals()里一般比较的比较全面比较复杂,这样效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高。

    hashCode()并不是完全可靠,哈希冲突

    3 使用的注意事项

    3.1 大量的并且快速的对象对比一般使用的hash容器,HashSet,HashMap,HashTable

    (以下 比较方式 可查看HashMap put方法验证)

    3.2  如果我们只是平时想对比两个对象 是否一致,则只重写一个equals(),然后利用equals()去对比也行的。

    equals  vs  ==

    当 equals 没重写时 equals 就是 == 比较两个对象 是否指向同一内存地址

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

    }

    equals  &  hashCode

    从equals来看

    1、that equal objects must have equal hash codes. 即:equals -> true hashCode 一定 ==

    2、equals -> false  hashCode 可能相同(hash冲突  However, the
     programmer should be aware that producing distinct integer results
     for unequal objects may improve the performance of hash tables. )

     从hashCode来看

    1、hashCode ==  ->equals true||false  (可能真的是同一个对象  可能hashCode冲突)

    2、hashCode !=   ->equals false

    equals

    * Indicates whether some other object is "equal to" this one.
    * <p>
    * The {@code equals} method implements an equivalence relation
    * on non-null object references

    * The {@code equals} method for class {@code Object} implements
    * the most discriminating possible equivalence relation on objects;
    * that is, for any non-null reference values {@code x} and
    * {@code y}, this method returns {@code true} if and only
    * if {@code x} and {@code y} refer to the same object
    * ({@code x == y} has the value {@code true}).
    * Object的equals实现: 最具有辨别力(其hashCode可能会有冲突的现象)的2个
    *非空引用 的等价性比较
    *也就是说,未重写时,只有x,y都是同一个对象的引用时(指向同一个对象),返回的才是true

    * Note that it is generally necessary to override the {@code hashCode}
    * method whenever this method is overridden, so as to maintain the
    * general contract for the {@code hashCode} method, which states
    * that equal objects must have equal hash codes.

    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}.
    // hash tables : HashTable  HashSet  HashMap

    * As much as is reasonably practical, the hashCode method defined
    * by class {@code Object} does return distinct integers for
    * distinct objects. (The hashCode may or may not be implemented
    * as some function of an object's memory address at some point
    * in time.)
    // 没重写  返回的是 对象某一时刻内存地址hash后的一个code (某一时刻 比如GC 时 使用标记-复制算法时 某些对象的内存地址会变化 对应着 hashCode也会变)

    <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.

    * 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.

    hashCode  &  HashMap

    参考:https://blog.csdn.net/qq_38182963/article/details/78940047

    源码:

    public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
    }

    static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
    // ^:异或 >>>:无符号右移 为啥要这样搞 后面研究下

     

    重写hashCode时注意事项

    重写hashCode方法时除了上述一致性约定,还有以下几点需要注意:

    (1)返回的hash值是int型的,防止溢出。

    (2)不同的对象返回的hash值应该尽量不同。(为了hashMap等集合的效率问题)

    (3)《Java编程思想》中提到一种情况

    “设计hashCode()时最重要的因素就是:无论何时,对同一个对象调用hashCode()都应该产生同样的值。如果在讲一个对象用put()添加进HashMap时产生一个hashCdoe值,而用get()取出时却产生了另一个hashCode值,那么就无法获取该对象了。所以如果你的hashCode方法依赖于对象中易变的数据,用户就要当心了,因为此数据发生变化时,hashCode()方法就会生成一个不同的散列码”。

    所以 自定义的对象 作为hash的key时 必须重写hashCode

    即使不是值比较  用原生的hashCode也是不安全的

    hashCode  返回的是 对象某一时刻内存地址hash后的一个code (某一时刻 比如GC 时 使用标记-复制算法时 某些对象的内存地址会变化 对应着 hashCode也会变)  hash的key也会变化 以前put的 就get不出来了

     实际应用:研究这些原理的应用价值(阿里规范 关于)

  • 相关阅读:
    Starlink星链计划能与5G抗衡?看一下马斯克吹过的牛逼
    代码安全性和健壮性:如何在if和assert中做选择?
    都说软件架构要分层、分模块,具体应该怎么做(一)
    物联网网关开发:基于MQTT消息总线的设计过程(上)
    Linq 集成化查询(1)
    给自己定位的技术总监
    lucene.net初接触
    人生就像一系统软件
    用Microsoft.Practices.Unity实现简单的依赖注入
    flv播放器参数
  • 原文地址:https://www.cnblogs.com/light-train-union/p/12918537.html
Copyright © 2011-2022 走看看