Java之hashCode的作用和equals方法的重构规则

这个是博主对hashcode的初步理解,以后加深了会再来更新:

1、hashcode是什么?

hashcode是对象的散列码,不同的对象几乎不一样,说几乎是因为还是可以一样的。

特点:每一个对象都有hashcode,默认的值是每一个对象的地址。

2、hashcode的作用:

博主已知的方便用户使用散列表插入数据,我们知道,集合有两种,list----可重复,set----不可重复。

其中set实现不可重复就需要使用到hashcode和equals方法。

散列表set是使用链表数组实现的,每一个列表被称作桶,而查找表中对象的位置使用的方法是:

1)、计算对象的散列码hashcode;

2)、公式:hashcode%桶数=索引;eg:某一个对象的散列码是76268,有128个桶,那么对应的这个对象的位置就是在第108个桶中。

而在插入对象到散列表中的时候使用的是同样的过程,只是这个时候可能会发现原有的位置被占用了,桶已经满了,这个时候就需要equals方法进行判断是否相等。

所以:

在重构equals方法的时候一定要重构hashcode方法,不然使用散列表的时候桶都找不到,更不用说下一步的判断是否是同一个对象了。

下面是示例代码:

    public static void main(String[] args) {
        String hello = "hello";
        StringBuilder helloSB = new StringBuilder(hello);

        String hello2 = "hello";
        StringBuilder hello2SB = new StringBuilder(hello2);

        System.out.println("hello‘s hashcode:" + hello.hashCode());
        System.out.println("helloSB‘s hashcode:" + helloSB.hashCode());
        System.out.println("hello2‘s hashcode:" + hello2.hashCode());
        System.out.println("hello2SB‘s hashcode:" + hello2SB.hashCode());

        Set stringSet = new HashSet();
        Set sbSet = new HashSet();

        stringSet.add(hello);
        System.out.println("======" + stringSet.contains(hello2));
        stringSet.add(hello2);

        sbSet.add(helloSB);
        sbSet.add(hello2SB);

        Person person1 = new Person(1, "eke");
        Person person2 = new Person(1, "eke");

        Set personSet = new HashSet();

        personSet.add(person1);
        personSet.add(person2);

        PersonWithHashCode code1 = new PersonWithHashCode(1, "eke");
        PersonWithHashCode code2 = new PersonWithHashCode(1, "eke");

        Set codeSet = new HashSet();

        codeSet.add(code1);
        codeSet.add(code2);

        System.out.println(stringSet.size());
        System.out.println(sbSet.size());
        System.out.println(personSet.size());
        System.out.println(codeSet.size());
    }

运行结果:  

hello‘s hashcode:99162322
helloSB‘s hashcode:39219479
hello2‘s hashcode:99162322
hello2SB‘s hashcode:2031787571
======true
1
2
2
1

  

下面是PersonWithHashCode,Person和PersonWithHashCode相比只是缺少了hashCode方法。

贴这个代码还有一点是重构了equals方法,这个方法的重构是要遵循一定规则的(图片来自《java核心技术卷II》):

public class PersonWithHashCode {
    private int id;
    private String name;

    public PersonWithHashCode(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int hashCode() {
        return id * 24 + name.hashCode();
    }

    @Override
    public boolean equals(Object object) {
        if (object == this)
            return true;

        if (object == null)
            return false;

        if (getClass() != object.getClass())
            return false;

        PersonWithHashCode person = (PersonWithHashCode) object;
        return this.id == person.id
                && Person.StringUtils.compare(name, person.getName());
    }

    static class StringUtils {
        static boolean compare(String a, String b) {
            if (a == null && b == null)
                return true;

            if (a == null && b != null) {
                return false;
            }

            if (a != null && b == null)
                return false;

            return a.equals(b);
        }

    }

}

  

时间: 2024-10-11 01:35:15

Java之hashCode的作用和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

Effective Java 第三版——10. 重写equals方法时遵守通用约定

Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8,甚至9的发布,Java语言发生了深刻的变化. 在这里第一时间翻译成中文版.供大家学习分享之用. 10. 重写equals方法时遵守通用约定 虽然Object是一个具体的类,但它主要是为继承而设计的.它的所有非 final方法(equals.hashCode.toStr

JAVA 注解的几大作用及使用方法详解

JAVA 注解的几大作用及使用方法详解 (2013-01-22 15:13:04) 转载▼ 标签: java 注解 杂谈 分类: Java java 注解,从名字上看是注释,解释.但功能却不仅仅是注释那么简单.注解(Annotation) 为我们在代码中添加信息提供了一种形式化的方法,是我们可以在稍后 某个时刻方便地使用这些数据(通过 解析注解 来使用这些数据),常见的作用有以下几种: 1.生成文档.这是最常见的,也是java 最早提供的注解.常用的有@see @param @return 等:

java类hashcode()、equals()、toString()方法

java中Object类中都有hashcode().equals().toString()这三个方法,因此java中所有的类中都有这三个方法. 在Object类中toString()方法的实现是打印对象的地址,这个打印出来人类是看不懂的,这个信息打印出来没有什么用处.所以在Effective Java这本书中,作者推荐我们尽量重写这个方法,使其打印出有用的信息.实现toString()方法是一个机械的繁琐的工作,所以我们应该借助成熟的类库来帮忙.java阵营中著名的类库guava可以很好的帮助我

java 数组的 toString 方法和 equals 方法以及 java.lang.Object 对象的 toString 方法和 equals 方法

1 public class Test { 2 public static void main(String[] args) { 3 int[] a = {1, 2, 4, 6}; 4 int[] b = a; 5 int[] c = {1, 2, 4, 6}; 6 7 //下面这个方法打印的是a数组的引用地址 8 System.out.println(a.toString()); 9 //下面这个方法比较的是两个数组的引用是否相等 10 System.out.println("a.equals

java课堂笔记------toString方法和equals方法

* 重写toString方法 * 当我们需要使用当前类的toString方法时,通常我们 * 就需要重写该方法.具体返回字符串的格式没有严格 * 要求,可根据将来实际开发中的需求而定.但通常反 * 回的字符串中应当包含当前类的属性值,以便了解当前 * 对象的信息. * 格式:(x,y) public String toString(){ return "(" + x + "," + y + ")"; } * 通常我们会重写一个类的equals方法

Java中编写一个完美的equals方法

首先看下Java语言规范对equals方法的要求: 1,自反性,对于任何非控引用x,x.equals(x)都应该返回true. 2,对称性,对于任何引用x和y,如果x.equals(y)返回true,那么y.equals(x)也应该返回true. 3,传递性,如果x.equals(y),y.equals(z)都返回true,那么,x.equals(z)返回true. 4,一致性,如果x和y引用的对象没有发生变化,那么无论调用多少次x.equals(y)都返回相同的结果. 5,对于任意非空引用x,

JAVA 面向对象补充[toString方法和equals方法]

一.toString  方法 这里的toString  和 C#的To string 是两回事. JAVA中to string : Object类中都有一个to string() 方法,创建的每一个类都会继承这个方法,返回一个对象的String 表示. 代码: 注释代码后结果: 取消注释后结果: 二.equals方法

java开发----自定义对象,重写equals方法

javaweb开发中,用到了好多自定义对象,这时候如果不重写equals方法,很多时候都会返回false, 因此我们必须习惯重写这个方法. 重点: 1.equals比较俩对象时比较的是对象引用是否指向同一地址 2.重写后比较的是俩者value是否相等 3.在重写的同时也要将hashcode方法重写--------至于为什么,在某个地方看到有人将此比作名字和身份证,感觉很恰当.(点击查看原因) 扩展: equals比较八大包装对象 (如Float,Double,Integer,Date,Point