一、概述

  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 集合的更多相关文章

  1. Java思考——HashSet集合如何保证元素的唯一性也就是不包含重复元素?

    首先将源码逐级找出来1.HashSet<String> hs=new HashSet<String>();         hs.add("hello"); ...

  2. Java学习:Set接口与HashSet集合存储数据的结构(哈希表)

    Set接口 java.util.Set接口 extends Collection接口 Set接口的特点: 不允许存储重复的元素 没有索引,没有带索引的方法,也不能使用普通的for循环遍历 java.u ...

  3. Java学习:集合双列Map

    数据结构 数据结构: 数据结构_栈:先进后出 入口和出口在同一侧 数据结构_队列:先进先出 入口和出口在集合的两侧 数据结构_数组: 查询快:数组的地址是连续的,我们通过数组的首地址可以找到数组,通过 ...

  4. Java中HashSet和HashMap

    Set中存储元素为什么不重复(即使hashCode相同)? HashSet中存放自定义类型元素时候,需要重写对象中的hashCode方法和equals方法, HashSet中存放自定义类型元素时候,需 ...

  5. HashSet集合介绍和哈希值

    HashSet集合介绍 ~java.util.Set接口 extends Collection 接口~Set接口的特点: 1.不允许存储重复的元素 2.没有索引,没有带索引的方法,也不能使用普通的fo ...

  6. HashSet集合的介绍和哈希值

    java.util.Set接口 extends Collection接口 Set接口的特点: 1.不允许存储重复的元素 2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历 java.uti ...

  7. 【转】Java如何克隆集合——深度拷贝ArrayList和HashSet

    原文网址:http://blog.csdn.net/cool_sti/article/details/21658521 原英文链接:http://javarevisited.blogspot.hk/2 ...

  8. JAVA学习第三十六课(经常使用对象API)— Set集合:HashSet集合演示

    随着Java学习的深入,感觉大一时搞了一年的ACM,简直是明智之举,Java里非常多数据结构.算法类的东西,理解起来就轻松多了 Set集合下有两大子类开发经常使用 HashSet集合 .TreeSet ...

  9. java集合(4)- java中HashSet详解

    HashSet 的实现 对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSe ...

随机推荐

  1. swiper使用总结-坑点汇总

    1.开发中遇到个坑,ScrollableTabView(选项卡)+swiper(轮播图)在安卓下,初始化的第一页不会渲染,需要在ScrollableTabView挂载完毕后再渲染swiper. 解决方 ...

  2. git crate&query&delete tag(九)

    root@vmuer-VirtualBox:/opt/myProject# git log --pretty=oneline0169b7a1c4bccb47e76711f353fd8d3864bde9 ...

  3. mysql where/having

    select * from t1 where id<5;select * from t1 where id<5; where 从t1中筛选内容 而having从*中筛选内容

  4. ESA2GJK1DH1K基础篇: 移植官方MQTT包,让TCP实现MQTT功能(以GPRS模块为例)

    前言 这节代码将在这一节的基础上实现 拷贝第一节测试里面的MQTT文件夹到当前工程 当前工程建个MQTT的文件夹,用于存放那个MQTT文件夹里面的内容 添加文件到里面 注意:::: 实际源码拷贝位置 ...

  5. cf1199解题报告

    目录 cf1199解题报告 A B C D E F cf1199解题报告 发一波水题. A 模拟 #include <bits/stdc++.h> #define ll long long ...

  6. hdu5111 树链剖分,主席树

    hdu5111 链接 hdu 思路 先考虑序列上如何解决. 1 3 2 5 4 1 2 4 5 3 这个序列变成 1 2 3 4 5 1 3 5 5 2 是对答案没有影响的(显然). 然后查询操作\( ...

  7. listings技巧

    1. \lstdefinestyle 参考 https://blog.csdn.net/ProgramChangesWorld/article/details/52142313 我们在使用listin ...

  8. 2018-2019-2 20165313 《网络对抗技术》 Exp 8 Web基础

    一.实践要求: (1).Web前端HTML(0.5分) 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML. (2).Web前端javascip ...

  9. IE 浏览器设置 打开新的选项卡而不是弹出窗口

    首先打开IE的页面  找到工具 —点击Internet选项

  10. DI 依赖注入之unity的MVC版本使用Microsoft.Practices.Unity1.2与2.0版本对比

    DI 依赖注入之unity的MVC版本使用Microsoft.Practices.Unity1.2与2.0版本对比 参考:https://www.cnblogs.com/xishuai/p/36702 ...