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有个整体认识,然后再学 ...
随机推荐
- 【安全研究】Domain fronting域名前置网络攻击技术
出品|MS08067实验室(www.ms08067.com) 千里百科 Domain Fronting基于HTTPS通用规避技术,也被称为域前端网络攻击技术.这是一种用来隐藏Metasploit,Co ...
- [系统重装日志3]autocad和ps破解安装
cad 以前保存的安装包注册机还让杀毒软件给自动删除了!!!(╯‵□′)╯︵┻━┻!!!又在网上找的注册机!!!(╯‵□′)╯︵┻━┻!!!软件安装包必须保存一份压缩的!!!(╯‵□′)╯︵┻━┻!! ...
- 在 .NET Core 中使用 ViewConfig 调试配置
介绍 .NET Core 中的配置包含了多个配置提供程序,包括了 appsettings.json,环境变量,命令行参数等,还有一些扩展的自定义提供程序,比如说 ApolloConfig,AgileC ...
- 在PHP7以上版本使用不了mysql扩展
旧程序使用了mysql扩展,而新环境却是PHP7以上版本,不支持mysql扩展,办法是将旧程序中的mysql相关内容修改为mysqli或PDO代码. 但是涉及修改的量大,那则可以包含(include ...
- day-06-集合-缓存机制-深浅copy
(1) is id ==用法 is 判断的是内存地址是否相同 id 查看内存地址:id相同,值一定相同,值相同,id不一定相同 == 比较判断是否相等 l1 = [1, 2, 3] l2 = [1, ...
- 深度学习---1cycle策略:实践中的学习率设定应该是先增再降
深度学习---1cycle策略:实践中的学习率设定应该是先增再降 本文转载自机器之心Pro,以作为该段时间的学习记录 深度模型中的学习率及其相关参数是最重要也是最难控制的超参数,本文将介绍 Lesli ...
- 【linux】驱动-10-pinctrl子系统
目录 前言 10. pinctrl子系统 10.1 参考路径 10.2 pinctrl子系统主要工作 10.2 pinctrl子系统格式说明 10.3 概念 10.4 实例分析 10.4.1 pin ...
- shell脚本 5 sed和awk
文本处理三剑客 在 Shell 下使用这些正则表达式处理文本最多的命令有下面几个工具: 命令 描述 grep 默认不支持扩展表达式,加-E 选项开启 ERE.如果不加-E 使用花括号要加转义符\{\} ...
- WPF之小米Logo超圆角的实现
某些新闻:小米logo换新,程序员一行代码(border-radius:19px)实现,目前此行代码价值200万 某程序员内心:所以还是因为我代码写太少了,所以这200万才没有我的份吗? 这事儿也成功 ...
- k8s集群移除node
先drain节点上的pod 使用kubectl drain node03 --delete-local-data --force --ignore-daemonsets 之后删除node [root@ ...