Java 之 HashSet 集合
一、概述
java.util.HashSet 是 Set 接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不一致)。
java.util.HashSet 底层的实现是一个 java.util.HashMap 支持。
HashSet 是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存储区和查找性能。保证元素唯一性的方式依赖于:hashCode 与 equals 方法。
特点:
1. 不允许存储重复的元素
2. 没有索引,也没有带索引的方法,不能使用普通 for 循环遍历
3. 是一个无序的集合,存储元素和取出元素的顺序有可能不一致
4. 底层是一个哈希表结构(查询的速度非常的快)
二、HashSet 集合存储数据的结构
1、哈希值
哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到地址,不是数据实际存储的物理地址)
在 Object 类中有一个方法,可以获取对象的哈希值。
int hashCode() 返回该对象的哈希码值。
hashCode 方法的源码:
public native int hashCode();
native:代表该方法调用的是本地操作系统的方法
2、哈希表
在 JDK1.8 之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。
JDK1.8中(之后),哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

存储流程图:

Demo:

JDK1.8引入红黑树大程度优化了HashMap的性能,那么对于我们来讲保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。
3、Set 集合不允许存储重复元素的原理

三、HashSet 存储自定义类型元素
给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一。
Demo:
1 // 创建自定义 student 类
2 public class Student {
3 private String name;
4 private int age;
5
6 public Student() {
7 }
8
9 public Student(String name, int age) {
10 this.name = name;
11 this.age = age;
12 }
13
14 public String getName() {
15 return name;
16 }
17
18 public void setName(String name) {
19 this.name = name;
20 }
21
22 public int getAge() {
23 return age;
24 }
25
26 public void setAge(int age) {
27 this.age = age;
28 }
29
30 @Override
31 public boolean equals(Object o) {
32 if (this == o)
33 return true;
34 if (o == null || getClass() != o.getClass())
35 return false;
36 Student student = (Student) o;
37 return age == student.age &&
38 Objects.equals(name, student.name);
39 }
40
41 @Override
42 public int hashCode() {
43 return Objects.hash(name, age);
44 }
45 }
46 // 创建测试类
47 public class HashSetDemo2 {
48 public static void main(String[] args) {
49 //创建集合对象 该集合中存储 Student类型对象
50 HashSet<Student> stuSet = new HashSet<Student>();
51 //存储
52 Student stu = new Student("于谦", 43);
53 stuSet.add(stu);
54 stuSet.add(new Student("郭德纲", 44));
55 stuSet.add(new Student("于谦", 43));
56 stuSet.add(new Student("郭麒麟", 23));
57 stuSet.add(stu);
58
59 for (Student stu2 : stuSet) {
60 System.out.println(stu2);
61 }
62 }
63 }
64 执行结果:
65 Student [name=郭德纲, age=44]
66 Student [name=于谦, age=43]
67 Student [name=郭麒麟, age=23]
四、遍历集合
1、增强 for 循环
for (Integer i : set) {
System.out.println(i);
}
2、迭代器遍历
Iterator<Integer> it = set.iterator();
while (it.hasNext()){
Integer n = it.next();
System.out.println(n);
}
Java 之 HashSet 集合的更多相关文章
- Java思考——HashSet集合如何保证元素的唯一性也就是不包含重复元素?
首先将源码逐级找出来1.HashSet<String> hs=new HashSet<String>(); hs.add("hello"); ...
- Java学习:Set接口与HashSet集合存储数据的结构(哈希表)
Set接口 java.util.Set接口 extends Collection接口 Set接口的特点: 不允许存储重复的元素 没有索引,没有带索引的方法,也不能使用普通的for循环遍历 java.u ...
- Java学习:集合双列Map
数据结构 数据结构: 数据结构_栈:先进后出 入口和出口在同一侧 数据结构_队列:先进先出 入口和出口在集合的两侧 数据结构_数组: 查询快:数组的地址是连续的,我们通过数组的首地址可以找到数组,通过 ...
- Java中HashSet和HashMap
Set中存储元素为什么不重复(即使hashCode相同)? HashSet中存放自定义类型元素时候,需要重写对象中的hashCode方法和equals方法, HashSet中存放自定义类型元素时候,需 ...
- HashSet集合介绍和哈希值
HashSet集合介绍 ~java.util.Set接口 extends Collection 接口~Set接口的特点: 1.不允许存储重复的元素 2.没有索引,没有带索引的方法,也不能使用普通的fo ...
- HashSet集合的介绍和哈希值
java.util.Set接口 extends Collection接口 Set接口的特点: 1.不允许存储重复的元素 2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历 java.uti ...
- 【转】Java如何克隆集合——深度拷贝ArrayList和HashSet
原文网址:http://blog.csdn.net/cool_sti/article/details/21658521 原英文链接:http://javarevisited.blogspot.hk/2 ...
- JAVA学习第三十六课(经常使用对象API)— Set集合:HashSet集合演示
随着Java学习的深入,感觉大一时搞了一年的ACM,简直是明智之举,Java里非常多数据结构.算法类的东西,理解起来就轻松多了 Set集合下有两大子类开发经常使用 HashSet集合 .TreeSet ...
- java集合(4)- java中HashSet详解
HashSet 的实现 对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSe ...
随机推荐
- Nginx on Docker 配置
docker run -d -p 8082:8082 --name two-nginx -v ~/workplace/nginx/html:/usr/share/nginx/html -v ~/wor ...
- docker自定义镜像上传阿里云
1.alpine制作jdk镜像 2.Alpine制作jre镜像(瘦身) 3.Docker镜像上传至阿里云 alpine制作jdk镜像 alpine Linux简介 1.Alpine Linux是一个轻 ...
- PEPE规范 和 垃圾回收
目录 1.python解释器的种类及特点 2.PEP8规范 3.解释型语言和编译型语言 4.bit.B.KB.MB.GB的关系 5.列举你所了解到python2和python3的区别 6.is和==的 ...
- 【线段树】【P5522】[yLOI2019] 棠梨煎雪
C [yLOI2019] 棠梨煎雪 Background 岁岁花藻檐下共将棠梨煎雪 自总角至你我某日辗转天边 天淡天青 宿雨沾襟 一年一会信笺却只见寥寥数言 --银临<棠梨煎雪> Desc ...
- concurrent (一)concurrent
参考文档: 跳跃表原理分析:https://blog.csdn.net/a1259109679/article/details/46442895 一.阻塞队列 ArrayBlockingQueue : ...
- Linux配置DNS
vi /etc/resolv.conf, 后面加上nameserver 114.114.114.114
- ASP.NET Core Windows服务开发技术实战演练
一.课程介绍 人生苦短,我用.NET Core!大家都知道如果想要程序一直运行在Windows服务器上,最好是把程序写成Windows服务程序:这样程序会随着系统的自动启动而启动,自动关闭而关闭,不需 ...
- HashTable源码
1. 为什么无法创建更大的数组? Attempts to allocate larger arrays may result in OutOfMemoryError 如果数组长度过大,可能出现的两种错 ...
- 修改Ubuntu系统的用户名和主机名
1.前言 当我们拿到别人拷贝的系统时,往往需要修改拷贝系统的密码.用户名和主机名,本文简单介绍在Ubuntu下如何进行相关配置文件的修改. 2.如何修改 (1)修改root的密码 运行下面的命令对对r ...
- losetup命令使用
1.losetup命令 Linux系统losetup命令用来设置循坏设备,循坏设备可以把文件虚拟成块设备,借此来模拟整个文件系统,让用户得以将其视为硬盘驱动器,光驱等设备,并挂入当作目录来使用. (1 ...