谈谈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应该

具有相同的值。

时间: 2024-11-13 22:06:58

谈谈java的hashcode使用场景的相关文章

谈谈Java的集合组件

让我们一起谈谈Java的集合组件 我们在使用Java的时候,都会遇到并使用到Java的集合.在这里通过自己的理解和网上的资源对Java的集合方面的使用做一个简单的讲解和总结. Java主要分为3个集合组件:Set(集).List(列表).Map(映射). Collection接口:Collection是最基本的集合接口,声明了适用于Java集合的通用方法.Set和List都继承了Collection,Map. Collection接口的方法: boolean add(Object o):向集合中

Java集合类的使用场景

目录 1. Java集合类基本概念 2. Java集合类架构层次关系 3. Java集合类的应用场景代码 1. Java集合类基本概念 在编程中,常常需要集中存放多个数据.从传统意义上讲,数组是我们的一个很好的选择,前提是我们事先已经明确知道我们将要保存的对象的数量.一旦在数组初始化时指定了这个数组长度,这个数组长度就是不可变的,如果我们需要保存一个可以动态增长的数据(在编译时无法确定具体的数量),java的集合类就是一个很好的设计方案了. 集合类主要负责保存.盛装其他数据,因此集合类也被称为容

java 翻盖hashCode()深入探讨 代码示例

package org.rui.collection2.hashcode; /** * 覆盖hashcode * 设计HashCode时最重要的因素 就是:无论何时,对同一个对象调用HashCode都应该产生同样的值, * 如果你的HashCode方法依赖于对象中易变的数据,用户就要当心了,因为此数据发生变化 时 * HashCode就会生成一个不同的散列码,相当于产生一个不同的健 * 此外 也不应该使HashCode依赖于具有唯一性的对象信息,尤其是使用this的值,这只能很糟糕, * 因为这

关于Java集合hashCode的总结

Java集合的hashCode是一个重要的知识点,在我们学习Java的过程中,也许会比较迷茫,所以这篇文章就给大家总结了一下. hashCode 的作用 在 Java 集合中有两类,一类是 List,一类是 Set 他们之间的区别就在于 List 集合中的元素师有序的,且可以重复,而 Set 集合中元素是无序不可重复的.对于 List 好处理,但是对于 Set 而言我们要如何来保证元素不重复呢?通过迭代来 equals() 是否相等.数据量小还可以接受,当我们的数据量大的时候效率可想而知(当然我

Java中hashCode的作用

转  http://blog.csdn.net/fenglibing/article/details/8905007 Java中hashCode的作用 2013-05-09 13:54 64351人阅读 评论(17) 收藏 举报  分类: JAVA实用笔记(142)  版权声明:本文为博主原创文章,未经博主允许不得转载. 以下是关于HashCode的官方文档定义: [plain] view plain copy hashcode方法返回该对象的哈希码值.支持该方法是为哈希表提供一些优点,例如,j

java 中hashcode和equals 总结

一.概述            在Java中hashCode的实现总是伴随着equals,他们是紧密配合的,你要是自己设计了其中一个,就要设计另外一个.当然在多数情况下,这两个方法是不用我们考虑的,直接使用默认方法就可以帮助我们解决很多问题.但是在有些情况,我们必须要自己动手来实现它,才能确保程序更好的运作. 1.1 规则 粗略总结一下在JavaDoc中所规定hashcode方法的合约:      Objects that are equal must have the same hash co

谈谈java的BlockingQueue

http://www.cnblogs.com/archy_yu/archive/2013/04/19/3018479.html 博客园 首页 新随笔 联系 管理 随笔- 92  文章- 0  评论- 825 谈谈java的BlockingQueue 最近在维护一个java工程,在群里面也就聊起来java的优劣!无奈一些Java的终极粉丝,总是号称性能已经不必C++差,并且很多标准类库都是大师级的人写的,如何如何稳定等等.索性就认真研究一番,他们给我的一项说明就是,在线程之间投递消息,用java已

谈谈java中静态变量与静态方法继承的问题

谈谈java中静态变量与静态方法继承的问题 学习的中如果遇到不明白或者不清楚的的时候,就是自己做些测试,自己去试试,这次我就做一个关于静态变量的继承和静态方法继承问题的测试. 首先我先建一个父类: 这样我在建一个子类: 这些都准备好以后,我对子类创建对象,然后用  类名.静态变量/静态方法  和  对象名.静态方法/静态变量  对他们输出的结果进行测试. 这样输出种类有: 这样我输出的结果是: 这样来总结一下: 1. 通过类名来调用子类中的静态变量和静态方法,当父类与子类相同时是,子类会隐藏父类

谈谈java中成员变量与成员方法继承的问题

谈谈java中成员变量与成员方法继承的问题 关于成员变量和成员方法的的继承问题,我也可以做一个小测试,来看看结果. 首先我们先创建一个父类: 其次再创建一个子类,子类中要比父类中少一个成员方法: 这样我们对子类创建对象,如果不创建对象,我们是无法访问子类的成员变量和成员方法的,因为“无法从静态上下文中引用非静态方法”.我们要输出有: 从以上的数据中,我们就可以得出的输出结果是 这样我们就可以得出结论. 总结: 1.   在结果中可以看出,子类的成员变量和成员方法,与其父类的相同的时候,子类就会覆