28.HashSet
4.HashSet集合
4.1HashSet集合概述和特点【应用】
底层数据结构是哈希表
不能保证存储和取出的顺序完全一致
不可以存储重复元素
没有索引,不能使用普通for循环遍历
4.2HashSet集合的基本应用【应用】
存储字符串并遍历
package com.itheima.myhashset; import java.util.HashSet;
import java.util.Iterator; public class HashSetDemo1 {
public static void main(String[] args) {
HashSet<String> hs=new HashSet<>();
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("java");
hs.add("java");
hs.add("java");
hs.add("java");
hs.add("java");
Iterator<String> it=hs.iterator();
while(it.hasNext()){
String next = it.next();
System.out.println(next);
}
System.out.println("============");
for (String h : hs) {
System.out.println(h);
}
}
}
4.3哈希值【理解】
哈希值简介
是JDK根据对象的地址或者字符串或者数字算出来的int类型的整数
如何获取哈希值
Object类中的public int hashCode():返回对象的哈希码值
哈希值的特点
- 如果没有重写hashCode方法,那么时根据对象的地址值计算出的哈希值
同一个对象多次调用hashCode()方法返回的哈希值是相同的,
不同对象的哈希值时不一样的
- 如果重写了hashCode方法,一般都是通过对象的属性值计算出哈希值
如果不同的对象属性值时一样的,那么计算出来的哈希值也是一样的
package com.itheima.myhashset;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(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;
}
//我们可以对Object类中的hashCode方法进行重写
//在重写时,就一般是根据对象的属性值来计算哈希值的
//此时跟对象的地址值就没有任何关系了
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类
package com.itheima.myhashset; /*
*
* 计算哈希值
*
* */
public class HashSetDemo2 {
public static void main(String[] args) {
Student s1=new Student("xiaozhi",23);
Student s2=new Student("xiaomei",22);
//因为在Object类中,是根据对象的地址值计算出来的哈希值
System.out.println(s1.hashCode());//1060830840
System.out.println(s1.hashCode());//1060830840 System.out.println(s2.hashCode());//2137211482
} }
4.4哈希表结构【理解】
JDK1.8以前 不包括jdk8底层采用数组 + 链表
- 数组的长度默认为16,加载因子为0.75
- 首先会获取元素的哈希值,计算出在数组中应存入的索引
- 判断该索引处是否为null,如果时null,直接添加
- 如果不是null则与链表中所有的元素,通过equals方法比较属性值
- 只要有一个相同,就不存,如果都不一样,才会存入集合

JDK1.8以后 底层进行了优化,由数组+链表+红黑树实现
节点个数少于等于8个
数组 + 链表
节点个数多于8个
数组 + 红黑树
- 当挂在下面的元素过多,那么不利于添加,也不利于查询,所以在JDK8以后,
- 当链表长度超过8的时候,自动转换为红黑树
- 存储流程不变

4.5HashSet集合存储学生对象并遍历【应用】
案例需求
创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
要求:学生对象的成员变量值相同,我们就认为是同一个对象
代码实现
学生类
package com.itheima.hashsettest;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类
没有重写hashCode方法,是根据对象的地址值计算的哈希值
哈希值不一样,那么计算出来应存入的索引就不一样
package com.itheima.hashsettest; import java.util.HashSet;
/*
* - 创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
- 要求:学生对象的成员变量值相同,我们就认为是同一个对象
*
*结论:
* 如果HashSet集合要存储自定义对象,那么必须重写hashCode和equals方法
* */
public class HashSetTest1 {
public static void main(String[] args) {
HashSet<Student> hs=new HashSet<>();
Student s1=new Student("xiaohei",23);
Student s2=new Student("xiaohei",23);
Student s3=new Student("xiaomei",22); hs.add(s1);
hs.add(s2);
hs.add(s3);
for (Student h : hs) {
System.out.println(h);
}
}
}
总结
Set:无序,无索引,不可以重复
HashSet:底层哈希表 重写hashCode方法和equals方法
TreeSet:底层:红黑树 必须给定排序规则
28.HashSet的更多相关文章
- Java Hour 28 HashSet
有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. Hour 28 HashSet 为查找而生 LinkedList查找效率低下, ...
- Java基础(面试题)
1:面向对象编程有很多重要的特性: 封装,继承,多态和抽象. 2:什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? (1)Java虚拟机是一个可以执行Java字节码的虚拟机进程.J ...
- java常见面试题及答案
java常见面试题及答案 来源 https://blog.csdn.net/hsk256/article/details/49052293 来源 https://blog.csdn.net/hsk25 ...
- JAVA基础部分面试
1:面向对象编程有很多重要的特性: 封装,继承,多态和抽象. 2:什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? (1)Java虚拟机是一个可以执行Java字节码的虚拟机进程.J ...
- java面试复习
1.jvm虚拟机 https://www.cnblogs.com/dingyingsi/p/3760447.html https://blog.csdn.net/qq_41701956/article ...
- Java集合---HashSet的源码分析
一. HashSet概述: HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持.它不保证set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用null元素. 二. ...
- Java API —— Set接口 & HashSet类 & LinkedHashSet类
1.Set接口 1)Set接口概述 一个不包含重复元素的 collection,无序(存储顺序和取出顺序不一致),唯一. (List有序,即存储顺序和取出顺序一致,可重复) ...
- Java基础知识强化之集合框架笔记41:Set集合之HashSet存储自定义对象并遍历练习
1. HashSet集合存储自定义对象并遍历.如果对象的成员变量值相同即为同一个对象 注意了: 你使用的是HashSet集合,这个集合的底层是哈希表结构. 而哈希表结构底层依赖:hashCode()和 ...
- 【转】Java 集合系列16之 HashSet详细介绍(源码解析)和使用示例--不错
原文网址:http://www.cnblogs.com/skywang12345/p/3311252.html 概要 这一章,我们对HashSet进行学习.我们先对HashSet有个整体认识,然后再学 ...
随机推荐
- vue中的.sync修饰符用法
在项目中接触到父组件传值给子组件的时候,想在子组件改变父组件传的值.(比如用于弹窗关闭) 但是正常来说,vue2是不允许子组件直接改父组件传进去的值的. 所以我们需要在子组件内定义自定义事件,通知父组 ...
- 计算机体系结构——CH2 指令系统
CH2 指令系统 右键点击查看图像,查看清晰图像 X-mind CH2 指令系统 数据表示 定义 指计算机硬件能够直接识别,可以被指令系统直接调用的那些数据类型 确定哪些数据类型用哪些数据表示实现,是 ...
- 致命错误:Python.h:没有那个文件或目录
yum search python3 | grep dev sudo yum install python3xxx-devel
- C++并发与多线程学习笔记--互斥量、用法、死锁概念
互斥量(mutex)的基本概念 互斥量的用法 lock(), unlock() std::lock_guard类模板 死锁 死锁演示 死锁的一般解决方案 std::lock()函数模板 std::lo ...
- [GDKOI2021] 普及组 Day1 总结
[ G D K O I 2021 ] 普 及 组 D a y 1 总 结 [GDKOI2021] 普及组 Day1 总结 [GDKOI2021]普及组Day1总结 长达3天的快乐GDKOI2021普及 ...
- Spring Boot 轻量替代框架 Solon 1.3.20 发布
Solon 是一个微型的Java开发框架.项目2018年启动,参考过大量前人作品:内核0.1m的身材,超高的跑分,以及良好的使用体验.支持:RPC.REST API.MVC.WebSocket.Soc ...
- 2021年春软件工程"助教团队"成员介绍
2021年春软件工程 助教团队 成员介绍 项目 内容 这个作业属于那个课程 2021春季学期软件工程(罗杰.任健) 这个作业的要求在哪里 团队介绍 姓名 照片 个人介绍 分工 刘Q 本团队的PM,和助 ...
- ES系列(二):基于多播的集群发现实现原理解析
ES作用超强悍的搜索引擎,除了需要具有齐全的功能支持,超高的性能,还必须要有任意扩展的能力.一定程度上,它是一个大数据产品.而要做扩展性,集群自然少不了.然而单独的集群又是不够的,能够做的事情太少,所 ...
- 使用Leaflet创建地图模块
背景 最近需要为某单位开发地图展示系统,因此开始涉略和使用Leaflet这个轻量级地图库. 创建基础地图需要以下几步 引入相关js和css文件,创建基础地图 <div id="map& ...
- 【译】Android NDK API 规范
[译]Android NDK API 规范 译者按: 修改R代码遇到Lint tool的报错,搜到了这篇文档,aosp仓库地址:Android NDK API Guidelines. 975a589 ...