一个有意思的 Java HashSet 问题

昨天,在百度的 java吧 看到有人问关于 HashSet 的问题。下面是他贴出的代码:

复制代码
 1 import java.util.HashSet;
 2 
 3 public class JavaTest
 4 {
 5     public static void main(String[] args)
 6     {
 7         HashSet<Person> hs = new HashSet<Person>();
 8         Person p = new Person("张三", 21);
 9         hs.add(p);
10         p.setName("李四");
11         p.setAge(22);
12         hs.add(p);
13         System.out.println(hs);
14     }
15 }
16 
17 class Person
18 {
19     private String name;
20     private int age;
21 
22     Person(String name, int age)
23     {
24         this.name = name;
25         this.age = age;
26     }
27 
28     public String getName()
29     {
30         return name;
31     }
32 
33     public void setName(String name)
34     {
35         this.name = name;
36     }
37 
38     public int getAge()
39     {
40         return age;
41     }
42 
43     public void setAge(int age)
44     {
45         this.age = age;
46     }
47 
48     public int hashCode()
49     {
50         return name.hashCode() + age * 21;
51     }
52 
53     public boolean equals(Object obj)
54     {
55         if (obj instanceof Person)
56         {
57             Person p = (Person) obj;
58             return name.equals(p.getName()) && age == p.getAge();
59         }
60         else
61         {
62             return false;
63         }
64     }
65 
66     public String toString()
67     {
68         return name + "--" + age;
69     }
70 }
复制代码

输出结果:

[李四--22, 李四--22]

楼主不明白为什么 HashSet 中的两个元素是一样的。不是说好了 Set 中不能有重复的元素吗?

我自信对 HashSet 还比较熟悉(尽管没研究过源代码),赶紧写了个回复,结果还没说到点子上。

后来楼主又改了一下 equals 方法和测试函数:

复制代码
import java.util.HashSet;

public class JavaTest
{
    public static void main(String[] args)
    {
        HashSet<Person> hs = new HashSet<Person>();
        Person p = new Person("张三", 21);
        hs.add(p);
        p.setName("李四");
        p.setAge(22);
        hs.add(p);
        hs.add(new Person("李四", 22));
        hs.add(new Person("张三", 21));
        
        System.out.println(hs);
    }
}

class Person
{
    private String name;
    private int age;

    Person(String name, int age)
    {
        this.name = name;
        this.age = age;
    }

    public String getName()
    {
        return name;
    }

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

    public int getAge()
    {
        return age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }

    public int hashCode()
    {
        return name.hashCode() + age * 21;
    }

    public boolean equals(Object obj)
    {
        //增加了判断是否为同一个对象
        if (this == obj)
        {
            return true;
        }
        
        if (obj instanceof Person)
        {
            Person p = (Person) obj;
            return name.equals(p.getName()) && age == p.getAge();
        }
        else
        {
            return false;
        }
    }

    public String toString()
    {
        return name + "--" + age;
    }
}
复制代码

输出结果是:

[李四--22, 李四--22, 张三--21]

 

如果理解 HashSet 原理,上面的结果倒也不难解释。

大家看看吧,挺有意思的,我觉得对理解 HashSet 有一定的帮助。

 

posted on   小米干饭  阅读(985)  评论(7编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示