• 谈谈java的hashcode使用场景


    hashcode是在Object就已经定义了一个方法,名叫散列码,来看看Object是怎么描述它的

        /**
         * 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如果没有覆盖重写,那么默认是由Object导出的对象存储地址。主要应用场景是HashMap和HashSet等等的Hash集合类里面

    实例1⃣️:String的hashCode()方法

    public static void main(String[] args) {
        String a1=new String("张");
        String a2=new String("张");
        String a3=new String("吴");
        HashSet<String> h1=new HashSet<>();
        h1.add(a1);
        h1.add(a2);
        h1.add(a3);
        System.out.println(h1);
    }

    输出结果:

    我明明add了三个对象进去,为什么HashSet里面只有两个元素,这是因为String覆盖了Object的hashcode()方法,我们来看看String的hashcode()

        /**
         * Returns a hash code for this string. The hash code for a
         * {@code String} object is computed as
         * <blockquote><pre>
         * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
         * </pre></blockquote>
         * using {@code int} arithmetic, where {@code s[i]} is the
         * <i>i</i>th character of the string, {@code n} is the length of
         * the string, and {@code ^} indicates exponentiation.
         * (The hash value of the empty string is zero.)
         *
         * @return  a hash code value for this object.
         */
        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的hashcode值为每个字符chat值相加。HashSet虽然添加了三个对象,但是其中两个对象的值是一样的,所以HashSet只保存两个元素。

    实例2⃣️:Object的hashCode()方法

    我们将实例1⃣️的中的String类型换成Object类型,代码如下:

    public static void main(String[] args) {
        Object a1=new Object();
        Object a2=new Object();
        Object a3=new Object();
        HashSet<Object> h1=new HashSet<>();
        h1.add(a1);
        h1.add(a2);
        h1.add(a3);
        System.out.println(h1);
    }

    输出结果:

    OK,HashSet保存了三个对象,没问题,因为Object的hashcode默认就是对象的存储地址

    实例3⃣️自定义类覆盖hashCode()方法

    我在这里定义了一个类,代码如下:

    public class HashCodeObject {
        private int a;
        
        public int getA() {
            return a;
        }
        public void setA(int a) {
            this.a = a;
        }
        @Override
        public boolean equals(Object obj) {
            if(obj instanceof HashCodeObject){
                return this.a==((HashCodeObject)obj).getA();
            }
            return false;
        }
        @Override
        public int hashCode() {
            return this.a;
        }
    }

    然后,再将实例2⃣️的Object换成我们自己定义的类,如下

    public static void main(String[] args) {
        HashCodeObject a1=new HashCodeObject();
        HashCodeObject a2=new HashCodeObject();
        HashCodeObject a3=new HashCodeObject();
        HashSet<HashCodeObject> h1=new HashSet<>();
        h1.add(a1);
        h1.add(a2);
        h1.add(a3);
        System.out.println(h1);
    }

    输出结果:

    注意,覆盖hashcode()方法的同时也要覆盖equal()方法,不然达不到效果,并且equal()和hashcode()定义必须要一致,如果equal()返回true,那么hashcode应该

    具有相同的值。

  • 相关阅读:
    社交需求和社交产品的更替
    腾讯产培生面经
    【C++基础】类class
    【C++基础】结构struct
    【C++基础】C-串知识整理
    GeoServer war包在tomcat7中配置遇到的一个问题
    pgrouting 2.0 的环境配置
    阿里2014年9月笔试中的一个算法设计题--擦黑板剩余数字
    VisualSVN Server的启动关闭脚本
    二叉树遍历(前序、中序、后序)的递归及非递归实现(小结)
  • 原文地址:https://www.cnblogs.com/pig-brother/p/7228370.html
Copyright © 2020-2023  润新知