一个有意思的 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 有一定的帮助。

时间: 2024-09-30 00:18:54

一个有意思的 Java HashSet 问题的相关文章

一个有意思的需求——中文匹配度

引言 最近LZ带头在做一个互联网项目,互联网的东西总是那么新鲜,这也难怪大部分猿友都喜欢互联网.这个互联网项目不仅让LZ开发了一个HBase大数据应用,近期的一次需求讨论会上,又出来一个小需求,蛮有意思的.这些需求在之前枯燥的企业内部应用开发中,还是很难见到的,毕竟内部应用更多的是业务流程的体现. 具体的需求这里不方便透露,但简单的描述一下需求,就是如何判断两个公司名是一个.这其实就是Java当中字符串的相等判断,最简单的当然是用equals来判断.但是由于实际情况是,公司名是由客户手动输出的,

一道很有意思的java线程题

这几天看结城浩的<java多线程设计模式>,跟着做一些习题,有几道题目很有意思,记录下自己的体会. 首先是题目(在原书212页,书尾有解答): public class Main { public static void main(String[] args) { try { Blackhole.enter(new Object()); } catch (InterruptedException e) { e.printStackTrace(); } } } public class Blac

Java——HashSet和TreeSet的区别

HashSetHashSet有以下特点? 不能保证元素的排列顺序,顺序有可能发生变化? 不是同步的? 集合元素可以是null,但只能放入一个null当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置.简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相 等注意,如果要把一个

Java HashSet和HashMap源码剖析

转自: Java HashSet和HashMap源码剖析 总体介绍 之所以把HashSet和HashMap放在一起讲解,是因为二者在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说HashSet里面有一个HashMap(适配器模式).因此本文将重点分析HashMap. HashMap实现了Map接口,允许放入null元素,除该类未实现同步外,其余跟Hashtable大致相同,跟TreeMap不同,该容器不保证元素顺序,根据需要该容器可能会对元素重新哈希,元素的顺序也会被重新打散,

一个简单的Java web服务器实现

一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用ServerSocket对象的accept方法,等待连接,连接成功会返回一个Socket对象,否则一直阻塞等待: 从Socket对象中获取InputStream和OutputStream字节流,这两个流分别对应request请求和response响应: 处理请求:读取InputStream字节流信息,转成字

一个强大的Java开源遥感处理软件(库)---Beam

1.Beam简介 为了在Hadoop中可以序列化HDF文件,在各种搜索之后,无意中发现了一个强大的Java开源软件,它就是Beam. 对于从事遥感的研究者来说,可以通过安装Beam,将它当成一个强大开源的遥感处理软件使用.虽然没有envi那么好用,还马马虎虎过得去.至少安装Beam,不用授权文件去破解~ 对于遥感软件开发人员来说,Beam的库简直一大利器!!! 用Java实现什么重投影.波段运算.主成分分析.图像裁剪.图像镶嵌,创建直方图,五花八门.各式各样.繁简不一的遥感操作,对它来说都是一碟

一个简单的java回调函数的实现

回调函数 回调函数涉及的3个函数 登记回调函数 回调函数 响应回调函数 简单的解释 你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货.在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件.回答完毕.来自知乎点击打开链接 代码的实现 首先有一个接口 interface CallB

一个简单的Java程序

一个.NET技术还是很菜的水平的猿人现在要去学习Java不知道是坏是好,无从得知啊! 不过在网上看了好多Java方面的简单例子,感觉Java还是蛮不错的么!不管以后怎么样啦,先开始自己的Java菜鸟之旅吧! 建立一个Java项目,建立一个属于自己的包,然后就开始自己的Java之旅... 创建的时候勾上这个生成main方法的选项,这个好像类似与我们.Net程序里控制台程序有木有.... 创建完成后就是这么一个样子,可以看到我们的包,还有给我们创建好自己的类,并且带了一个静态的main方法咋看就像.

一个简单的java web 项目

本文实现一个简单的 java web 项目,包括以下5个功能: 1. 登录 用户默认主页index.jsp , 可选择登录功能,输入用户名和密码,若登录成功,则进入产品管理总页面main.jsp.若不成功仍退回index.jsp 2. 注册 用户默认主页index.jsp ,  可选择注册功能 ,若注册,则进入 register.jsp 3. 管理产品(增加,删除,查看) 登录成功后,进入产品管理总页面main.jsp.第一次进入main.jsp,默认显示所有产品列表.在此页面上更实现 查询某个