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. 【安全研究】Domain fronting域名前置网络攻击技术

    出品|MS08067实验室(www.ms08067.com) 千里百科 Domain Fronting基于HTTPS通用规避技术,也被称为域前端网络攻击技术.这是一种用来隐藏Metasploit,Co ...

  2. [系统重装日志3]autocad和ps破解安装

    cad 以前保存的安装包注册机还让杀毒软件给自动删除了!!!(╯‵□′)╯︵┻━┻!!!又在网上找的注册机!!!(╯‵□′)╯︵┻━┻!!!软件安装包必须保存一份压缩的!!!(╯‵□′)╯︵┻━┻!! ...

  3. 在 .NET Core 中使用 ViewConfig 调试配置

    介绍 .NET Core 中的配置包含了多个配置提供程序,包括了 appsettings.json,环境变量,命令行参数等,还有一些扩展的自定义提供程序,比如说 ApolloConfig,AgileC ...

  4. 在PHP7以上版本使用不了mysql扩展

    旧程序使用了mysql扩展,而新环境却是PHP7以上版本,不支持mysql扩展,办法是将旧程序中的mysql相关内容修改为mysqli或PDO代码. 但是涉及修改的量大,那则可以包含(include ...

  5. day-06-集合-缓存机制-深浅copy

    (1) is id ==用法 is 判断的是内存地址是否相同 id 查看内存地址:id相同,值一定相同,值相同,id不一定相同 == 比较判断是否相等 l1 = [1, 2, 3] l2 = [1, ...

  6. 深度学习---1cycle策略:实践中的学习率设定应该是先增再降

    深度学习---1cycle策略:实践中的学习率设定应该是先增再降 本文转载自机器之心Pro,以作为该段时间的学习记录 深度模型中的学习率及其相关参数是最重要也是最难控制的超参数,本文将介绍 Lesli ...

  7. 【linux】驱动-10-pinctrl子系统

    目录 前言 10. pinctrl子系统 10.1 参考路径 10.2 pinctrl子系统主要工作 10.2 pinctrl子系统格式说明 10.3 概念 10.4 实例分析 10.4.1 pin ...

  8. shell脚本 5 sed和awk

    文本处理三剑客 在 Shell 下使用这些正则表达式处理文本最多的命令有下面几个工具: 命令 描述 grep 默认不支持扩展表达式,加-E 选项开启 ERE.如果不加-E 使用花括号要加转义符\{\} ...

  9. WPF之小米Logo超圆角的实现

    某些新闻:小米logo换新,程序员一行代码(border-radius:19px)实现,目前此行代码价值200万 某程序员内心:所以还是因为我代码写太少了,所以这200万才没有我的份吗? 这事儿也成功 ...

  10. k8s集群移除node

    先drain节点上的pod 使用kubectl drain node03 --delete-local-data --force --ignore-daemonsets 之后删除node [root@ ...