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. 开源项目月刊《HelloGitHub》第 60 期

    兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程.对开源社区感兴趣 人群的月刊,月刊的内容包括:各种编 ...

  2. vue中常见的问题以及解决方法

    有一些问题不限于 Vue,还适应于其他类型的 SPA 项目. 1. 页面权限控制和登陆验证 页面权限控制 页面权限控制是什么意思呢? 就是一个网站有不同的角色,比如管理员和普通用户,要求不同的角色能访 ...

  3. Python爬虫知乎文章,采集新闻60秒

    前言 发现很多人需要新闻的接口,所以自己去搜索了下,发现知乎上正好有对应的用户每天发布新闻简讯,所以自己想写一个新闻的爬虫.如果想做成接口的话,可以加上flask模块即可,这里就暂时只进行爬虫部分的编 ...

  4. 北航OO第二单元作业总结(2.1~2.3)

    在经过第一单元初步认识面向对象编程思想后,本蒟蒻开始了第二单元--多线程部分的学习.本单元的作业是构造符合条件的"目的选层电梯"模型,自行设计调度算法,进行合理调度,完成所有乘客的 ...

  5. Dropping Balls UVA - 679

      A number of K balls are dropped one by one from the root of a fully binary tree structure FBT. Eac ...

  6. matlab逻辑类型

    matlab逻辑类型 matlab逻辑表达式输出:1为真,0为假. matlab关系操作符: 关系操作符 说明 < 小于 <= 小于等于 > 大于 >= 大于等于 == 等于 ...

  7. Java双刃剑之Unsafe类详解

    前一段时间在研究juc源码的时候,发现在很多工具类中都调用了一个Unsafe类中的方法,出于好奇就想要研究一下这个类到底有什么作用,于是先查阅了一些资料,一查不要紧,很多资料中对Unsafe的态度都是 ...

  8. linux 安装rabbitMQ详细教程

    经过第一次的安装失败, 第二次总算是成功了, 这里总结一下. 第一步:下载版本对应的rpm安装包 1. 下载Erlang安装包:RabbitMQ是Erlang语言编写,所以Erang环境必须要有,注: ...

  9. 关于Hexo博客NEXT主题(Gmini)站点图标不显示,显示错误的解决办法

    关于Hexo博客NEXT主题(Gmini)站点图标不显示,显示错误的解决办法   最近闲着没事自己利用Hexo和Github搭了个博客,但是在NEXT(Gmini)主题优化时,出了很多错误,图标不显示 ...

  10. 《机器学习Python实现_10_09_集成学习_bagging_stacking原理及实现》

    介绍 前面对模型的组合主要用了两种方式: (1)一种是平均/投票: (2)另外一种是加权平均/投票: 所以,我们有时就会陷入纠结,是平均的好,还是加权的好,那如果是加权,权重又该如何分配的好?如果我们 ...