×

Java 信息技术 学习 日记 编程 集合

一道有意思的java集合练习题

Shine_Light Shine_Light 发表于2022-02-28 20:26:41 浏览1126 评论0

抢沙发发表评论

今天在学习Java的时候,看到了一道非常有意思的题跟大家分享,顺便记录一下,免得以后忘了

题目出处:韩顺平零基础30天学会Java P552(www.bilibili.com/video/BV1fh411y7R8?p=552)

题目:

    Person类有属性id(int)和属性name(String), Person类已按id和name重写了hashcode和equals方法,问以下代码输出什么

HashSet set = new HashSet();
Person p1 = new Person(1001, "AA");
Person p2 = new Person(1001, "BB");
set.add(p1);
set.add(p2);
p1.name = "CC";
set.remove(p1);
System.out.println(set);
set.add(new Person(1001, "CC"));
System.out.println(set);
set.add(new Person(1001, "AA"));
System.out.println(set);


输出结果:

[Homework.Person@103a9, Homework.Person@10789]

[Homework.Person@103a9, Homework.Person@10789, Homework.Person@10789]

[Homework.Person@103a9, Homework.Person@10789, Homework.Person@10789, Homework.Person@ffc9]


输出结果分别输出了2 3 4个对象,而我的答案是1 2 3个对象,最终我找到了问题所在,归根结底还是底层机制没学好


图文详解:

前面的代码都没什么大问题

HashSet set = new HashSet();
Person p1 = new Person(1001, "AA");
Person p2 = new Person(1001, "BB");
set.add(p1);
set.add(p2);


从这开始就有问题了,这里很容易就会掉进陷阱里

p1.name = "CC";
set.remove(p1);
System.out.println(set);

现在假设p1的哈希值为001,哈希运算后在数组的索引为1

现在假设p2的哈希值为002,哈希运算后在数组的索引为2

将p1的name更改为"CC"

现在的p1因为属性变动了,所以哈希值变更为003

set调用remove方法并传入p1,而此时p1的哈希值为003,进行哈希运算后获得的索引为3,而索引为3的位置是空,所以不影响原来的元素

所以输出2个对象


set.add(new Person(1001, "CC"));
System.out.println(set);

现在添加一个Person对象, 这个对象的id与name和p1一样,所以哈希运算后的索引也为3,而索引为3上没有元素,所以添加成功

输出3个对象


set.add(new Person(1001, "AA"));
System.out.println(set);

接下来又添加了一个Person对象,这个Person对象的属性与最开头的p1一样,所以进行哈希运算后索引为1

但是索引1的位置已经有对象了,所以使用对象的hashcode方法和equals方法进行比较,而新的对象的属性与现在p1的属性不同,所以新的对象会被添加到链表上

最终输出4个对象

分享到:

群贤毕至

访客