判断Set里的元素是否重复、==、equals、hashCode方法研究-代码演示

被测试类,没有重写hasCode()和equals()方法:

package niukewang;

import java.util.Objects;

public class setClass {

    String a;
    String b;
    public setClass(String a, String b)
    {
        this.a=a;
        this.b=b;
    }
}

测试类:

package niukewang;

import java.util.HashSet;
import java.util.Set;

public class test1 {

    public static void main(String args[])
    {
        setClass s1=new setClass("http://www.yjbys.com/", "");
        setClass s2=new setClass("http://www.yjbys.com/", "");
        setClass s3=new setClass("http://www.yjbys.com/", "");

        Set<setClass> set=new HashSet<>();
        set.add(s1);
        set.add(s2);
        set.add(s3);

        String ss=new String("Hello");
        String ss1=new String("Hello");
        System.out.println(ss==ss1);
        System.out.println(ss.equals(ss1));
        System.out.println(ss.hashCode()==ss1.hashCode());

        System.out.println("set....");

        System.out.println(s1==s2);
        System.out.println(s1.equals(s2));
        System.out.println(s1.hashCode()==s2.hashCode());
        System.out.println("Number is "+set.size());
    }
}

输出结果:
false   (string不是同一个对象)
true    (只要值相同就行了)
true    (hashcode也相同)
set....
false    (不是同一个对象)
false    
false
Number is 2

这是没有覆盖hashCode()和equals()方法的情况。

被测试类覆盖hashCode()和equals()方法:

package niukewang;

import java.util.Objects;

public class setClass {

    String a;
    String b;
    public setClass(String a, String b)
    {
        this.a=a;
        this.b=b;
    }

    public int hashCode() {
        return a.hashCode();
    }

    public boolean equals(Object obj)
    {
        if(obj==null) return false;

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

        final setClass s=(setClass)obj;

        return Objects.equals(this.a, s.a);
    }
}

覆盖之后,hascode的值就是设置的a的hashcode,equals()比较的也是a的hashcode的值。
测试结果输出:

false
true
true
set....
false
true
true
Number is 1

set内部实现实际是map,在处理map的key的时候调用了hashcode方法,HashMap中有代码如下

 static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

调试证明:把元素往set中添加时,首先会对比hashcode是否相等,如果hashcode不相等就直接往set中加这个元素,如果 hashcode相等就对比equals方法,如果equals不相等就往set中加这个元素,所以set的元素重复性是根据hashcode和 equals方法来判断的,

对于为什么覆盖equals方法就一定要覆盖hashcode方法的原因也显示了出来:由于是先调用hashcode方法的,如果不覆盖hashcode 方法,默认会去取内存的物理地址作为生成hashcode的依据,那么两个不同的对象的hashcode必然不同的,于是直接结束添加了,根本没法调用到 equals方法,就不用说equals内部实现如何了,不管equals是返回true还是false都没机会调用到了。

由于set内部是用map实现的,所以往map中put元素的时候是一样的原理。

证明如果不重写hashcode方法,无论equals是返回true还是返回false都没有用,因为在调用equals方法之前会先调用hashcode方法,在调用hashcode方法的时候

就已经被认为这些对象全部是不重复的元素,直接往set中添加这些对象,并完成添加,equals方法就没有机会调用到。

借鉴博文:http://www.cnblogs.com/langtianya/p/4421582.html

时间: 2024-08-10 17:00:02

判断Set里的元素是否重复、==、equals、hashCode方法研究-代码演示的相关文章

Java对象的equals,hashCode方法

今天下午研究了半天hashcode()和equals()方法,终于有了一点点的明白,写下来与大家分享(zhaoxudong 2008.10.23晚21.36). 1. 首先equals()和hashcode()这两个方法都是从object类中继承过来的. equals()方法在object类中定义如下:   public boolean equals(Object obj) { return (this == obj); } 很明显是对两个对象的地址值进行的比较(即比较引用是否相同).但是我们必

java之判断集合中的元素是否重复

第1章 判断集合元素唯一的原理 1.1 ArrayList的contains方法判断元素是否重复原理 ArrayList的contains方法会使用调用方法时,传入的元素调用equals方法依次与集合中的旧元素所比较,从而根据返回的布尔值判断是否有重复元素.此时,当ArrayList存放自定义类型时,由于自定义类型在未重写equals方法前,判断是否重复的依据是地址值,所以如果想根据内容判断是否为重复元素,需要重写元素的equals方法. 1.2 HashSet的add/contains等方法判

equals(),hashcode()方法详解

Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法,今天就来介绍一些这两个方法的作用. equals()和hashCode()方法是用来在同一类中做比较用的,尤其是在容器里如set存放同一类对象时用来判断放入的对象是否重复. 这里我们首先要明白一个问题: equals()相等的两个对象,hashcode()一定相等,equals()不相等的两个对象,却并不能证明他们的hashcode()不相等.换

Object类中的toString(),equals(), hashCode()方法之间的关系

1.在没有重写之前: 1) toString()方法返回的是对象的:Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例).at 标记符"@"和此对象哈希码的无符号十六进制表示组成.换句话说,该方法返回一个字符串,它的值等于: getClass().getName() + '@' + Integer.toHexString(hashCode())  比如:[email protected] 2) equals():对于任何非空引用值 x 和 y

集合 源码分析判断是否是同一元素的策略

List:equals 对于List集合(ArrayList.LinkedList等):仅仅是通过判断两个对象的[equals]方法是否为true. 以下为 ArrayList 的部分源码: public boolean contains(Object o) { return indexOf(o) >= 0; } public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementD

当改变数组的某一个对象里的元素的时候,为什么其他对象里的元素也发生改变了

当运用多层循环的时候,会出现一种情况,就是当想改变数组的某一个对象里的元素的时候,其他对象里的元素页跟着发生了改变.根据条件已经定位到了某一个对象,但是改变之后发现,其他的还是也都改变了. 原因就是: 数组是引用对象,数组变量存储在栈,元素数据存储在堆中,将数组赋值不同的对象,所以赋值对象都指向堆同一个数据,因此改变其中一个数组对象里的元素,其他对象里的元素也会发生改变 解决方法: var arr = JSON.parse(JSON.stringify(array)); 原文地址:https:/

如何编写出高质量的 equals 和 hashcode 方法?

什么是 equals 和 hashcode 方法? 这要从 Object 类开始说起,我们知道 Object 类是 Java 的超类,每个类都直接或者间接的继承了 Object 类,在 Object 中提供了 8 个基本的方法,equals 方法和 hashcode 方法就是其中的两个. equals 方法:Object 类中的 equals 方法用于检测一个对象是否等于另一个对象,在 Object 类中,这个方法将判断两个对象是否具有相同的引用,如果两个对象具有相同的引用,它们一定是相等的.

批量插入数据, 将DataTable里的数据批量写入数据库的方法

大量数据导入操作, 也就是直接将DataTable里的内容写入到数据库 通用方法: 拼接Insert语句, 好土鳖 1. MS Sql Server:   使用SqlBulkCopy 2. MySql: adapter.update()批量更新 MySqlBulkLoader, 这个是从文件里边到的, 有个实现是先将DATATable编程CSV文件, 在用MySqlBulkLoader导入MySql 参考文章: http://theonetechnologies.com/outsourcing/

为什么重写equals方法需同时重写hashCode方法?

举个小例子来看看,如果重写了equals而不重写hashcode会发生什么样的问题: import java.util.HashMap; public class MyTest { private static class Person { int idCard; String name; public Person(int idCard, String name) { this.idCard = idCard; this.name = name; } @Override public bool