一个有意思的 Java HashSet 问题
昨天,在百度的 java吧 看到有人问关于 HashSet 的问题。下面是他贴出的代码:
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);
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 (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]
楼主不明白为什么 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 有一定的帮助。
一个有意思的 Java HashSet 问题的更多相关文章
- Java HashSet和TreeSet【笔记】
Java HashSet和TreeSet[笔记] PS:HashSet.TreeSet 两个类是在 Map 的基础上组装起来的类 HashSet 类注释 1.底层实现基于 HashMap,所以迭代时不 ...
- Java HashSet和HashMap源码剖析
转自: Java HashSet和HashMap源码剖析 总体介绍 之所以把HashSet和HashMap放在一起讲解,是因为二者在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说Ha ...
- Java——HashSet和TreeSet的区别
HashSetHashSet有以下特点 不能保证元素的排列顺序,顺序有可能发生变化 不是同步的 集合元素可以是null,但只能放入一个null当向HashSet集合中存入一个元素时,HashSe ...
- Java HashSet对txt文本内容去重(统计小说用过的字或字数)
Java HashSet对txt文本内容去重(统计小说用过的字或字数) 基本思路: 1.字节流读需要去重的txt文本.(展示demo为当前workspace下名为utf-8.txt的文本) 2.对读取 ...
- Linux环境下部署完JDK后运行一个简单的Java程序
前言 前一篇文章详细讲解了如何在Windows环境下安装虚拟机+Linux系统,并且成功部署了JDK. 不过部署完JDK之后,我们判断部署是否成功的依据是看"java -version&qu ...
- 一个简单的Java web服务器实现
前言 一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用S ...
- linux下一个有意思的问题(文件名以短划线或空格开头)
linux下一个有意思的问题(文件名以短划线开头) 这本是无意中的一个发现. 在linux下,文件名中含有 - 是没有问题,但是如果文件名是以-作为第一个字符的,那么就比较麻烦了. 问题演示 看这里, ...
- 【Jetlang】一个高性能的Java线程库
actor Jetlang 提供了一个高性能的Java线程库,该库是 JDK 1.5 中的 java.util.concurrent 包的补充,可用于基于并发消息机制的应用. .net的MS CCR ...
- Java HashSet和LinkedHashSet的用法
Java HashSet和LinkedHashSet的用法 类HashSet和LinkedHashSet都是接口Set的实现,两者都不能保存重复的数据.主要区别是HashSet不保证集合中元素的顺序, ...
随机推荐
- Asp.Net MVC之防止用户注入脚本参数
假设有一个Controller,代码如下: public string Browse(string genre) { string message = "Store.Browse, Genr ...
- MVC :“已添加了具有相同键的项”
最近将一个项目从ASP.NET MVC 3升级至刚刚发布的ASP.NET MVC 5.1,升级后发现一个ajax请求出现了500错误,日志中记录的详细异常信息如下: System.ArgumentEx ...
- FreeSWITCH技巧:如何向通话的另一方号码发送dtmf?
注:这里的文章都是本人的日常总结,请尊重下个人的劳动成果,转载的童鞋请注明出处,谢谢. 如您转载的文章发生格式错乱等问题而影响阅读,可与本人联系,无偿提供本文的markdown源代码. 联系邮箱:ji ...
- unity, Awake的调用时机
Awake是在setActive(true)时才会被调用,不过如果再setActive(false)然后重新setActive(true)的话,Awake就不会再被调用了,也就是说Awake能保证仅被 ...
- 181213 - 解决Android的应用APP背景色突然被改变的问题
在魅族最新的特定版本出现APP背景突然被改变颜色的问题 出问题的机型相关信息 型号:魅族16th Plus Android 版本: 8.1.0 安全补丁 版本: 2018年10月1日 Flyme 版本 ...
- C语言第十一回合:预处理命令的集中营
C语言第十一回合:预处理命令的集中营 [学习目标] 1. 宏定义 2. 文件包括"处理 3. 条件编译 预处理命令:能够改进程序设计的 ...
- LNK2019: 无法解析的外部符号(函数实现没有加namespace前缀导致)
问题描述: 在A.h中,我写了如下函数 namespace XXX { void func(); } 在A.cpp中,我写了如下实现 #include "A.h" using na ...
- 跟着百度学PHP[17]-PHP扩展CURL的用法详解
实现的功能: 1.实现远程获取和采集内容2.实现PHP 网页版的FTP上传下载3.实现模拟登陆:去一个邮件系统,curl可以模拟cookies4.实现接口对接(API),数据传输等:通过一个平台发送短 ...
- glibc中malloc的详细解释_转
glibc中的malloc实现: The main properties of the algorithms are:* For large (>= 512 bytes) requests, i ...
- GPU 属性
struct cudaDeviceProp { ]; /**< 设备的ASCII标识 */ size_t totalGlobalMem; /**< 可用的全局内存量,单位字节 */ siz ...