import java.util.HashSet;
import java.util.Objects;
/**
* @author 精灵
* @time 2020-08-08
**/
class person
{
int age;
String name;
public person(int age , String name){
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
person person = (person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(age, name);
}
}
public class HashSetTest {
public static void main(String[] args) {
HashSet a = new HashSet();
person p01 = new person(12,"AA");
person p02 = new person(21,"BB");
a.add(p01);
a.add(p02);
p01.name = "CC";
a.remove(p01);
System.out.println(a);
/*
*此行输出结果为
* [person{age=12, name='CC'}, person{age=21, name='BB'}]
* HashSet中的remove方法是通过HashCode来找到元素地址的,而
* HashCode中又是通过所盛放的类的属性来计算哈希值的,因此在
* 存放时是按照12,AA所映射出的哈希值盛放的,而现在p01映射出
* 的HashCode随着其中的属性已经变成12,CC映射出的HashCode值
* 所以删除的是12,CC所映射出的HashCode的地址上的内容,而这
* 个地址根本没有存放内容,所以没有删除成功。
*
*/
a.add(new person(12,"CC"));
System.out.println(a);
/*
*此行输出结果为
* [person{age=12, name='CC'}, person{age=12, name='CC'}, person{age=21, name='BB'}]
*为什么此时set中竟然会出现重复的结果?
* 因为现在存放新new出来的person的地方是属性12,CC所计算出的
* 哈希值,而在上几步的代码中,第一次存放的的12,CC这个对象是
* 通过12,AA计算出的哈希值进行存放的,也就是说在目前这一步中
* 第一个12,CC实际存放在了12,AA的地址之中。所以他的哈希码并
* 不实际对应自己的存储位置。
*
*/
a.add(new person(12,"AA"));
System.out.println(a);
/*
*此行输出结果为
* [person{age=12, name='CC'}, person{age=12, name='CC'}, person{age=12, name='AA'}, person{age=21, name='BB'}]
*此时添加的新对象就是按照12,AA的属性映射的值,而原来按照相同属
*性映射出的地址现在实际存放的是12,CC,所以在哈希值相同的情况下
* 用equals进行对比 发现其中的AA和CC并不相等,所以新来的AA作为
* CC的尾被加入到链表中。
*
*/
}
}
Java中HashSet中成员属性的修改对HashSet存储方式的影响
最新推荐文章于 2022-09-01 19:21:23 发布