HashSet 介绍, equals() 和hashcode()方法介绍

看大佬的博客。

https://blog.csdn.net/woshiluoye9/article/details/56286187

HashSet 介绍, equals() 和hashcode()方法介绍
2017-02-21 15:59:43 请叫我王老魔 阅读数 871 收藏 更多
分类专栏: java
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/woshiluoye9/article/details/56286187

第一点,Set集合中是不允许有重复元素的,
第二点,Set集合中是无顺序的
第三点:

  • 为什么 add方法在添加String类型和普通的对象Person的时候结果不太一样,在它的帮助文档中是这样解释的
  • //Adds the specified element to this set if it is not already present. More formally,
  • adds the specified element e to this set if this set contains no element e2
  • such that (enull ? e2null : e.equals(e2)).
  • If this set already contains the element, the call leaves the set unchanged and returns false.
    可以看到,对于增加一个非空对象e,首先要保证集合中不存在一个对象,其地址和e相同,同时要满足在存在的集合中不存在e2 使得 e.equals(e2)成立,
    那么这个就可以解释了,对于String对象,equals方法比较的是内容,所以只有一个a被添加到set中
    对于Person对象,equals方法比较的是地址,所以两个对象都会被添加到Set中
    */

关于第三点的更详细的原理解释:
当使用HashSet 时,hashCode()方法就会得到调用,判断已经存储在集合中的对象的hash code 值是否与增加的对象的 hash code 值一致;如果不一致,直接加进去;如果一致,再进行 equals 方法的比较,equals 方法如果返回 true,表示对象已经加进去了,就不会再增加新的对象,否则加进去

// 举几个例子更加了解上面说的几点

import java.util.HashSet;

public class HashSetTest {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
// 第一点,Set集合中是不允许有重复元素的,
// 第二点,Set集合中是无顺序的
hashSet.add(“a”);
hashSet.add(“b”);
hashSet.add(“c”);
hashSet.add(“d”);
hashSet.add(“a”);
System.out.println(hashSet); // d b c a
/*第三点:
* 为什么 add方法在添加String类型和普通的对象Person的时候结果不太一样,在它的帮助文档中是这样解释的
* //Adds the specified element to this set if it is not already present. More formally,
* adds the specified element e to this set if this set contains no element e2
* such that (enull ? e2null : e.equals(e2)).
* If this set already contains the element, the call leaves the set unchanged and returns false.
可以看到,对于增加一个非空对象,首先要保证两个对象的地址是不一致的才能添加,
同时要满足在存在的集合中不存在e2 使得 e.equals(e2)成立,
那么这个就可以解释了,对于String对象,equals方法比较的是内容,所以只有一个a被添加到set中
对于Person对象,equals方法比较的是地址,所以两个对象都会被添加到Set中
*/

    /*
     * 当使用HashSet 时,hashCode()方法就会得到调用,判断已经存储在集合中的对象的hash code 值
     * 是否与增加的对象的 hash code 值一致;如果不一致,直接加进去;
     * 如果一致,再进行 equals 方法的比较,equals 方法如果返回 true,
     * 表示对象已经加进去了,就不会再增加新的对象,否则加进去
     */
    //对于String类型,它重写了hashCode()方法, 它的hashcode值的计算方法如下:

// The hash code for a String object is computed as
// s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1]

    hashSet.clear();
    String s1= new String("a");
    String s2=new String("a");
    // 因此在添加String的时候,s1和s2的hashcode值是一样的,之后就回去比较equals方法,也一样,所以不添加
    hashSet.add(s1);
    hashSet.add(s2);
    System.out.println(hashSet); //[a]

    hashSet.clear();
    People people1 =new People("zhangsan");
    People people2 =new People("lisi");
    // 在添加People的时候,people1和people2的hashcode值是不一样的,因此添加到hashSet中去
    hashSet.add(people1);
    hashSet.add(people2);
    System.out.println(hashSet); //[Set.People@3e2de41d, Set.People@36db4bcf]

}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

知识点介绍:equals 方法一旦被重写,hashcode方法也一定要被重写,反之亦然。

equals方法的特性:
a) 自反性:x.equals(x)应该返回 true
b) 对称性:x.equals(y)为 true,那么y.equals(x)也为true。
c) 传递性:x.equals(y)为 true 并且y.equals(z)为true,那么 x.equals(z)也应该为 true。
d) 一致性:x.equals(y)的第一次调用为 true,那么 x.equals(y)的第二次、第三次、第 n次调用也应该为true,前提条件是在比较之间没有修改 x 也没有修改 y。
e) 对于非空引用 x,x.equals(null)返回false。

hashcode()方法特性:
a) 在 Java 应用的一次执行过程当中,对于同一个对象的 hashCode 方法的多次调用,他们应该返回同样的值(前提是该对象的信息没有发生变化) 。
b) 对于两个对象来说,如果使用equals方法比较返回true,那么这两个对象的hashCode值一定是相同的。
c) 对于两个对象来说,如果使用equals方法比较返回false,那么这两个对象的hashCode值不要求一定不同(可以相同,可以不同) ,但是如果不同则可以提高应用的性能。
d) 对于Object类来说,不同的Object对象的hashCode值是不同的(Object类的hashCode值表示的是对象的地址,它会把地址转化为一个整数) 。

//Object类中你的源代码, native代表着这是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI(java native interface)接口调用其他语言来实现对底层的访问。

public native int hashCode();

// equals方法源代码
public boolean equals(Object obj) {
return (this == obj);
}
// toString() 方法源代码,Object类的toString返回: 类名+@+对象的地址(转化为16进制的整形字符串)
public String toString() {
return getClass().getName() + “@” + Integer.toHexString(hashCode());
}

1
2
3
4
5
6
7
8
9
10
11
12
13

如果想实现一个功能:People类根据名字来进行能否加到hashSet中去的一个判断依据, 即如果两个People对象名字相同,那么只能允许一个对象添加到hashSet中去,
实现方法,重写equals和hashCode 方法,记住这两个方法是要一起重写的,一个被重写,另一个也要被重写, 有两种重写方式,一个是自己重写,一个系统自动生成,下面代码中有介绍

class People {
String name;
String age;

public People(String name) {
    // TODO Auto-generated constructor stub
    this.name = name;
}

// 可以自己重写方法
public int hashCode() {
    return this.name.hashCode();
}
public boolean equals(Object obj) {
    if (this == obj){  // 判断地址是否相同
        return true;
    }
    if (obj == null){ // 判断是否为空
        return false;
    }
    if (obj instanceof People){  // 是否是People对象
        People people = (People) obj;
        if(this.name.equals(people.name)){
            return true;
        }
    }
    return false;

}



// eclipse 提供了自带的生成的办法,方便快捷,通过点击 Source----Generate hashCode() and equals()

// @Override
// public int hashCode() {
// final int prime = 31;
// int result = 1;
// result = prime * result + ((name == null) ? 0 : name.hashCode());
// return result;
// }
//
// @Override
// public boolean equals(Object obj) {
// if (this == obj)
// return true;
// if (obj == null)
// return false;
// if (getClass() != obj.getClass())
// return false;
// People other = (People) obj;
// if (name == null) {
// if (other.name != null)
// return false;
// } else if (!name.equals(other.name))
// return false;
// return true;
// }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用HashSet时,如果要将自定义对象作为元素存储在其中,则需要重写该对象的hashCode()和equals()方法hashCode()方法用于确定元素的哈希值,用于在HashSet中确定元素的位置。 equals()方法用于比较两个元素是否相等。如果两个元素的hashCode()值相同,则会调用equals()方法来确定它们是否相等。 重写这两个方法的规则如下: - hashCode()方法: 1. 在同一对象中多次调用hashCode()应该返回相同的整数。 2. 如果equals()比较两个对象相等,则它们的hashCode()返回值应该相同。 3. hashCode()返回值不一定唯一,不同对象可能会返回相同的整数。 - equals()方法: 1. 自反性: 对于任何非空引用x,x.equals(x)应该返回true。 2. 对称性: 对于任何非空引用x和y,当且仅当y.equals(x)返回true时,x.equals(y)也应该返回true。 3. 传递性: 对于任何非空引用x,y,z,如果x.equals(y)返回true,并且y.equals(z)返回true,那么x.equals(z)也应该返回true。 4. 一致性:对于任何非空引用x和y,多次调用x.equals(y)应该始终返回相同的结果在使用HashSet的时候,为了保证对象的唯一性,需要重写对象的hashCodeequals方法hashCode方法用于生成对象的哈希码,HashSet在添加对象时会使用该哈希码来判断对象是否重复。 equals方法用于判断两个对象是否相等。如果重写了hashCode方法,一般也要重写equals方法。 重写这两个方法时,需要遵循以下规则: 1.如果两个对象相等,那么它们的hashCode值一定相等。 2.如果两个对象的hashCode值相等,那么它们不一定相等。 3.equals方法需要遵循传递性,对称性和自反性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值