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

  1. Java Hour 28 HashSet

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. Hour 28 HashSet 为查找而生 LinkedList查找效率低下, ...

  2. Java基础(面试题)

    1:面向对象编程有很多重要的特性: 封装,继承,多态和抽象. 2:什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? (1)Java虚拟机是一个可以执行Java字节码的虚拟机进程.J ...

  3. java常见面试题及答案

    java常见面试题及答案 来源 https://blog.csdn.net/hsk256/article/details/49052293 来源 https://blog.csdn.net/hsk25 ...

  4. JAVA基础部分面试

    1:面向对象编程有很多重要的特性: 封装,继承,多态和抽象. 2:什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? (1)Java虚拟机是一个可以执行Java字节码的虚拟机进程.J ...

  5. java面试复习

    1.jvm虚拟机 https://www.cnblogs.com/dingyingsi/p/3760447.html https://blog.csdn.net/qq_41701956/article ...

  6. Java集合---HashSet的源码分析

    一.  HashSet概述: HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持.它不保证set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用null元素. 二.  ...

  7. Java API —— Set接口 & HashSet类 & LinkedHashSet类

    1.Set接口     1)Set接口概述         一个不包含重复元素的 collection,无序(存储顺序和取出顺序不一致),唯一.  (List有序,即存储顺序和取出顺序一致,可重复) ...

  8. Java基础知识强化之集合框架笔记41:Set集合之HashSet存储自定义对象并遍历练习

    1. HashSet集合存储自定义对象并遍历.如果对象的成员变量值相同即为同一个对象 注意了: 你使用的是HashSet集合,这个集合的底层是哈希表结构. 而哈希表结构底层依赖:hashCode()和 ...

  9. 【转】Java 集合系列16之 HashSet详细介绍(源码解析)和使用示例--不错

    原文网址:http://www.cnblogs.com/skywang12345/p/3311252.html 概要 这一章,我们对HashSet进行学习.我们先对HashSet有个整体认识,然后再学 ...

随机推荐

  1. Git命令太多记不住?有了这个神器,从此告别输入命令行

    一 .SourceTree简介 SourceTree 是 Windows 和Mac OS X 下免费的 Git 和 Hg 客户端,拥有可视化界面,容易上手操作.同时它也是Mercurial和Subve ...

  2. Genymotion下载模拟器慢

    •问题来源 Genymotion 是个很不错的 Android 模拟器,系统更新快,启动速度快: 但是服务器在国外,Android 镜像下载起来那个速度就不敢恭维了: 当然如果你可以[科学,上网]就另 ...

  3. Android学习之探究Fragment

    •碎片是什么 Fragment是一种可以嵌入在活动中的UI片段,能够让程序更加合理和充分地利用大屏幕的空间: 出现的初衷是为了适应大屏幕的平板电脑,可以将其看成一个小型Activity,又称作Acti ...

  4. [.net] 关于Exception的几点思考和在项目中的使用(三)

    本文链接: https://www.cnblogs.com/hubaijia/p/about-exceptions-3.html 系列文章: 关于Exception的几点思考和在项目中的使用(一) 关 ...

  5. [Fundamental of Power Electronics]-PART I-3.稳态等效电路建模,损耗和效率-3.1 直流变压器模型

    3.1 直流变压器模型 如图3.1所示,任何开关变换器都包含三个部分:功率输入,功率输出以及控制输入.输入功率按控制输入进行特定的功率变换输出到负载.理想情况下,这些功能将以100%的效率完成,因此 ...

  6. 【笔记】《算法竞赛入门》习题7-6 UVa12113_重叠的正方形

    title: 习题7-6 UVa12113_重叠的正方形 date: 2021-01-31 19:08:00 categories: 算法竞赛入门 tags: 数据结构 算法 UVa <算法竞赛 ...

  7. Vue CLI 是如何实现的 -- 终端命令行工具篇

    Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供了终端命令行工具.零配置脚手架.插件体系.图形化管理界面等.本文暂且只分析项目初始化部分,也就是终端命令行工具的实现. 0. 用法 ...

  8. [kuangbin]专题六 最小生成树 题解+总结

    kuangbin专题链接:https://vjudge.net/article/752 kuangbin专题十二 基础DP1 题解+总结:https://www.cnblogs.com/RioTian ...

  9. Trees on the level UVA - 122

    Trees are fundamental in many branches of computer science (Pun definitely intended). Current stateo ...

  10. 一次错误使用 go-cache 导致出现的线上问题

    话说一个美滋滋的上午, 突然就出现大量报警, 接口大量请求都响应超时了. 排查过程 查看服务器的监控系统, CPU, 内存, 负载等指标正常 排查日志, 日志能够响应的结果也正常. request.l ...