昨天,在百度的 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 问题的更多相关文章

  1. Java HashSet和TreeSet【笔记】

    Java HashSet和TreeSet[笔记] PS:HashSet.TreeSet 两个类是在 Map 的基础上组装起来的类 HashSet 类注释 1.底层实现基于 HashMap,所以迭代时不 ...

  2. Java HashSet和HashMap源码剖析

    转自: Java HashSet和HashMap源码剖析 总体介绍 之所以把HashSet和HashMap放在一起讲解,是因为二者在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说Ha ...

  3. Java——HashSet和TreeSet的区别

    HashSetHashSet有以下特点 不能保证元素的排列顺序,顺序有可能发生变化 不是同步的 集合元素可以是null,但只能放入一个null当向HashSet集合中存入一个元素时,HashSe ...

  4. Java HashSet对txt文本内容去重(统计小说用过的字或字数)

    Java HashSet对txt文本内容去重(统计小说用过的字或字数) 基本思路: 1.字节流读需要去重的txt文本.(展示demo为当前workspace下名为utf-8.txt的文本) 2.对读取 ...

  5. Linux环境下部署完JDK后运行一个简单的Java程序

    前言 前一篇文章详细讲解了如何在Windows环境下安装虚拟机+Linux系统,并且成功部署了JDK. 不过部署完JDK之后,我们判断部署是否成功的依据是看"java -version&qu ...

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

    前言 一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用S ...

  7. linux下一个有意思的问题(文件名以短划线或空格开头)

    linux下一个有意思的问题(文件名以短划线开头) 这本是无意中的一个发现. 在linux下,文件名中含有 - 是没有问题,但是如果文件名是以-作为第一个字符的,那么就比较麻烦了. 问题演示 看这里, ...

  8. 【Jetlang】一个高性能的Java线程库

    actor  Jetlang 提供了一个高性能的Java线程库,该库是 JDK 1.5 中的 java.util.concurrent 包的补充,可用于基于并发消息机制的应用. .net的MS CCR ...

  9. Java HashSet和LinkedHashSet的用法

    Java HashSet和LinkedHashSet的用法 类HashSet和LinkedHashSet都是接口Set的实现,两者都不能保存重复的数据.主要区别是HashSet不保证集合中元素的顺序, ...

随机推荐

  1. 设置SSH编码为中文

    http://www.qzz.in/?post=198下面是详细方法: 方法1: vi /etc/sysconfig/i18n 将内容改为 LANG="zh_CN.GB18030" ...

  2. js+CSS 实现可以编辑的下拉列表框

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...

  3. python-hanoi

    #!/usr/bin/env python #-*- coding:utf-8 -*- ############################ #File Name: hanoi.py #Autho ...

  4. Reveal使用教程

    Reveal使用教程 Reveal是用于透视程序整体结构的一个软件,软件收费89美刀,试用期30天,不过好在有破解版,无需担心花钱的问题​ 在然后呢,软件在哪下,可以在我的github上下载到破解版本 ...

  5. eclipse的源代码编辑窗口可以拖出来单独使用的哦

    这在你边阅读文档边写代码的时候非常有用的!整个eclipse窗口吧,太大,挡事,把源代码编辑的标签拖出来,就成为一个单独的窗口了,也就记事本大小,而且代码提示自动补全什么的一样不少~ 虽然这个代码编辑 ...

  6. DMA—直接存储区访问

    本章参考资料:< STM32F4xx 中文参考手册> DMA 控制器章节.学习本章时,配合< STM32F4xx 中文参考手册> DMA 控制器章节一起阅读,效果会更佳,特别是 ...

  7. C1编译器的实现

    总览 词法.语法分析 分析方案 词法 语法 符号表 类型系统 AST 语义检查 EIR代码生成器 MIPS代码生成器 寄存器分配 体系结构相关特性优化 使用说明 编译 运行 总览 C1语言编译器及流程 ...

  8. deepin linux 15.3安装完eclipse启动报错An error has occurred.

    原因是系统中安装了jdk9 导致的. 卸载jdk9就可以了 $ java -version Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings ...

  9. CSRF学习笔记之CSRF的攻击与防御以及审计【00x3】

    Hight.php完整代码如下: <?php if (isset($_GET['Change'])) { // Turn requests into variables $pass_curr = ...

  10. jQuery 实战读书笔记之第二章:选择元素

    基本选择器 html 代码如下,后面的 js 使用的 html 基本大同小异. <!doctype html> <html> <head> <title> ...