一、概述

  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. 【librosa】及其在音频处理中的应用

    [持续更新] display specshow(data[, x_coords, y_coords, x_axis, …]) Display a spectrogram/chromagram/cqt/ ...

  2. 5.服务注册与发现Consul,简学API,手动注册和删除服务

    package main import ( httptransport "github.com/go-kit/kit/transport/http" mymux "git ...

  3. ABP 报错 System.InvalidOperationException: 实例失败。

    错误:System.InvalidOperationException: 实例失败. 解决:数据库链接写错了,斜杠的问题 core:两根斜杠 .net framework:一根斜杠 core的写法: ...

  4. SPA项目开发之动态树+数据表格+分页

    SPA项目开发之动态树+数据表格+分页 动态生成NavMenu导航菜单(只支持2级菜单) <el-menu key="" index=""> < ...

  5. js如何遍历map类型

    1.forEach遍历: map.forEach(function(value,key){ console.log(value,key); }); 函数中第一个参数是属性值,第二个参数是属性 2.fo ...

  6. 回溯法 | 图的m着色问题

    学习链接:算法 图的M着色问题 虽然今早9点才醒来,10点才来教室,但是coding得很高效.吃个早餐,拉个粑粑的时间,就把算法书上的[图的m着色]问题看明白了,大脑里也形成了解决问题的框架. 其实这 ...

  7. CF888G XOR-MST trie,贪心

    CF888G XOR-MST 链接 CF888G 思路 trie上贪心,先左右两边连边,再用一条边的代价连起左右两颗树.因为内部的边一定比跨两棵树的边权笑,显然是对的. 代码自己瞎yy的.启发式合并 ...

  8. sort函数实现多条件排序

    js的sort方法,我们一般传入一个回调用于单排序,也就根据某一个条件排序,那么一个场景需要多条件排序(多重排序),我们怎么处理呢? 如下例子,我们按学生的总分排序,如果总分相等,我们再按照语文成绩排 ...

  9. kali linux 更换镜像源

    编辑sources.list文件 leafpad /etc/apt/sources.list #aliyun 阿里云 deb http://mirrors.aliyun.com/kali kali-r ...

  10. React 获取真实Dom v8.6.2版本

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...