美文网首页
探讨hashCode

探讨hashCode

作者: YoursBG | 来源:发表于2019-02-24 20:04 被阅读0次

    在Java中,Object类是所有类的父类。
    今天,我们一起探讨Object类中的hashCode方法,以及hashCode在我们实际使用过程中的作用。
    查看Object类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();
    

    正如hashCode方法所描述的:
    1.如果两个对象相等,调用hashCode方法返回的int值相等;
    2.两个不相等的对象返回不同的hashCode值,有利于提高hash table的性能;

    描述归描述,我们通过一个实际例子,说明hashCode如何提高hash table的性能。
    Java中,关于hash table的集合类有Hashtable、HashMap、ConcurrentHashMap、LinkedHashMap,通过其中之一HashMap来说明。
    HashMap中,常常使用方法get、set,查看get源码:

        public V get(Object key) {
            Node<K,V> e;
            return (e = getNode(hash(key), key)) == null ? null : e.value;
        }
    
        static final int hash(Object key) {
            int h;
            return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
        }
    
        final Node<K,V> getNode(int hash, Object key) {
            Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
            if ((tab = table) != null && (n = tab.length) > 0 &&
                (first = tab[(n - 1) & hash]) != null) {
                if (first.hash == hash && // always check first node
                    ((k = first.key) == key || (key != null && key.equals(k))))
                    return first;
                if ((e = first.next) != null) {
                    if (first instanceof TreeNode)
                        return ((TreeNode<K,V>)first).getTreeNode(hash, key);
                    do {
                        if (e.hash == hash &&
                            ((k = e.key) == key || (key != null && key.equals(k))))
                            return e;
                    } while ((e = e.next) != null);
                }
            }
            return null;
        }
    

    通过一个例子了解getNode的算法,假设我们有三个房间1,2,3,每个房间都可以存储很多物品,每存储一件物品时,需要使用相同规格集装箱包装。
    现在有铅笔,剪刀,橡皮,直尺,篮球,足球需要存储。
    存储进房间前,在纸上记录每件物品对应的房间号。
    铅笔 ——> 房间1
    剪刀 ——> 房间2
    橡皮 ——> 房间2
    直尺 ——> 房间3
    篮球 ——> 房间3
    足球 ——> 房间3
    所有物品都存储进对应房间,且每个物品都使用相同规格集装箱包装。
    OK,现在需要取出篮球

    get("篮球");
    

    步骤:
    1.在纸上找出篮球对应的房间号3(房间号3相当于篮球的hash值)
    2.打开房间3,看到有三个相同的集装箱(直尺、篮球、足球),需要一个一个尝试打开,寻找出篮球。(别问我为什么还用集装箱包装,程序不是人,它需要遍历)
    getNode算法大概就是步骤1,2所描述的。
    从其算法可以观察到,如果直尺、篮球、足球有一一对应的房间,那么在步骤2时,打开房间,只会有一个集装箱,就不需要聚个遍历。
    因此,正如hashCode源码所描述的,两个不相等的对象返回不同的hashCode值,有利于提高hash table的性能。

    getNode在步骤2时,有两种方式去寻找集装箱,一种是线性链表,一种红黑树。//TODO,后续会超链接线性链表、红黑树


    总结

    hashCode的作用
    1.如果两个对象相等,调用hashCode方法返回的int值相等;
    2.两个不相等的对象返回不同的hashCode值,有利于提高hash table的性能;

    hashCode.getNode算法
    1.在纸上寻找房间号;
    2.对应房间里遍历集装箱;

    相关文章

      网友评论

          本文标题:探讨hashCode

          本文链接:https://www.haomeiwen.com/subject/nthbyqtx.html