【JAVA语言-第16话】集合框架(三)——Set、HashSet、LinkedHashSet、TreeSet集合的详细解析

目录

Set集合

1.1 概述 

1.2 特点

1.3 HashSet集合

1.3.1 概述 

1.3.2 哈希表 

1.3.3 哈希值

1.3.4 练习

1.3.5 HashSet存储自定义类型元素

1.4 LinkedHashSet集合

1.4.1 概述

1.4.2 特点

1.4.3 练习

1.5 TreeSet集合

1.5.1 概述

1.5.2 练习

1.6 HashSet、LinkedHashSet、TreeSet 的异同点


Set集合

1.1 概述 

         java.util.Set:是一个接口,和List一样,也是继承自Collection,常用的实现类有TreeSet、HashSet,LinkedHashSet。

1.2 特点

  • 存取无序,存储的顺便和取出的数据不一定一致。 
  • 没有索引,不能通过索引操作元素。
  • 不可以存储重复的元素。相同元素的判断:哈希值相同,内容相同。

1.3 HashSet集合

1.3.1 概述 

         java.util.HashSet:在Java中,HashSet是一种基于哈希表的集合实现。它继承自AbstractSet类并实现了Set接口。HashSet类在内部使用哈希表来存储元素,并且不保证元素的顺序。它允许存储唯一的元素,不允许重复。HashSet提供了常量时间的查找、插入和删除操作,因此可以在大多数情况下提供高效的性能。 

1.3.2 哈希表 

        在jdk1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一个哈希值的元素都存储在一个链表中,但是当位于一个链表中的元素较多,即哈希值相等的元素较多时,通过Key值依次查找的效率较低;所以在jdk1.8中,哈希表存储采用数组+链表/红黑树实现,当链表的长度超过8时,将链表转换为红黑树,这样大大减少了查找时间。

1.3.3 哈希值

        是一个十进制整数,由系统随机给出(就是对象的地址,是一个逻辑地址,是模拟出来得到的地址,不是数据实际存储的物理地址),在Object类中有一个方法,可以获取对象的哈希值。

public native int hashCode():返回该对象的哈希码值。

        

toString方法的源码:内部就是调用hashCode()方法
        public String toString(){
            return getClass().getName() + "@" + Integer.toHaxString(hashCode());
        }

1.3.4 练习

package com.zhy.coll;import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;public class TestHashSet {public static void main(String[] args) {//多态,接口引用 指向 实现类对象Set<Integer> set = new HashSet<>();//往Set集合中添加元素,Set和List一样继承了Collection,所有两个类操作元素有着相似的方法set.add(10);set.add(20);set.add(30);//猜猜:这个元素能不能存储进Set集合?set.add(10);//打印Set集合印证一下//输出:初始化Set集合:[20, 10, 30]//明明添加了4个元素,但是最终Set集合中只有三个,这就是Set区别于List的地方,前者是不允许存储重复数据的//且存储是10,20,30,但是输出且不是按照存储数据打印,这也是Set区别于List的地方,前者是无序的System.out.println("初始化Set集合:" + set);//遍历集合,可以使用迭代器或者增强for循环//1.使用迭代器Iterator<Integer> iterator = set.iterator();while(iterator.hasNext()){Integer integer = iterator.next();System.out.print(integer + " ");}//2.使用增强forfor(Integer integer : set){System.out.print(integer + " ");}}
}

1.3.5 HashSet存储自定义类型元素

        Set集合保证元素唯一:(String,Integer,...Student,Person),自定义的类如果想要使用Set集合存储,必须重写hashCode方法和equals方法,才能过滤掉重复的数据。

 源代码:

package com.zhy.coll;import java.util.Objects;public class Persion {private String name;private int age;public Persion() {}public Persion(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;}/*** 自定义类型,重写equals方法*  比较规则:name 和 age 内容都相同,返回true,否则,返回false* @param o* @return*/@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Persion persion = (Persion) o;if (age != persion.age) return false;return name != null ? name.equals(persion.name) : persion.name == null;}/*** 获取对象的hashCode,必须和equals一起重写* @return*/@Overridepublic int hashCode() {int result = name != null ? name.hashCode() : 0;result = 31 * result + age;return result;}/*** 重写toString,返回对象的内容,如果不重写,默认对象的地址* @return*/@Overridepublic String toString() {return "Persion{" +"name='" + name + '\'' +", age=" + age +'}';}
}
package com.zhy.coll;import java.util.HashSet;public class TestPersion {public static void main(String[] args) {//使用HashSet存储String类型的数据//排除重复元素规则:首先比较两个值的hashCode是否相同,其次比较两个值的内容是否相同//如果两种情况都相同,HashSet会判定为这两个值是同一个元素,只会存储一个//如果hashCode相同,内容不相同,那么会以链表的形式存储在一个hashCode下面HashSet<String> set1 = new HashSet<>();String str1 = new String("abc");String str2 = new String("abc");String str3 = new String("重地");String str4 = new String("通话");System.out.println("str1的hashCode:" + str1.hashCode());System.out.println("str2的hashCode:" + str2.hashCode());System.out.println("str3的hashCode:" + str3.hashCode());System.out.println("str4的hashCode:" + str4.hashCode());System.out.println("str1 和 str2是否是同一个元素:" + (str1.hashCode() == str2.hashCode() && str1.equals(str2)));System.out.println("str3 和 str4是否是同一个元素:" + (str3.hashCode() == str4.hashCode() && str3.equals(str4)));set1.add(str1);set1.add(str2);set1.add(str3);set1.add(str4);System.out.println("初始化String类型的Set集合:" + set1);System.out.println("========================================================");//使用HashSet存储自定义类型Persion的数据,为了保证Set集合不重复存储的特性,自定义类型必须重写hashCode和equals方法//比较规则:// 根据name和age获取唯一的hashCode值,然后在比较两个对象的名称+年龄是否相同// 二者都相同,代表同一个对象,不重复存储HashSet<Persion> set2 = new HashSet<>();Persion p1 = new Persion("张三",18);Persion p2 = new Persion("张三",18);Persion p3 = new Persion("李思",28);System.out.println("p1的hashCode:" + p1.hashCode());System.out.println("p2的hashCode:" + p2.hashCode());System.out.println("p3的hashCode:" + p3.hashCode());System.out.println("p1 和 p2是否是同一个元素:" + (p1.hashCode() == p2.hashCode() && p1.equals(p2)));set2.add(p1);set2.add(p2);set2.add(p3);System.out.println("初始化Persion类型的Set集合:" + set2);}
}

 输出结果:

1.4 LinkedHashSet集合

1.4.1 概述

        java.util.LinkedHashSet:在Java中,LinkedHashSet是一种集合类,它是HashSet的子类。它继承了HashSet的特性,同时还保持了元素的插入顺序。与HashSet不同的是,LinkedHashSet使用链表来维护集合中元素的顺序。

1.4.2 特点

        底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序。

1.4.3 练习

源代码:

package com.zhy.coll;import java.util.Iterator;
import java.util.LinkedHashSet;public class TestLinkedHashSet {public static void main(String[] args) {//创建集合,存储Integer类型的数据LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<Integer>();//往集合中添加数据linkedHashSet.add(10);linkedHashSet.add(20);linkedHashSet.add(30);linkedHashSet.add(40);linkedHashSet.add(20);//遍历集合,迭代器或者增强forSystem.out.print("使用迭代器遍历集合:");Iterator<Integer> iterator = linkedHashSet.iterator();while (iterator.hasNext()){Integer integer = iterator.next();System.out.print(integer + " ");}}
}

输出结果:      

        查看集合的数据,不仅遍历的顺序和添加的顺序一致,还过滤掉了重复数据。

 

1.5 TreeSet集合

1.5.1 概述

        java.util.TreeSet:在Java中,TreeSet是一个实现了Set接口的有序集合。它是通过红黑树数据结构实现的,可以保证元素按照自然排序或者通过Comparator进行排序。TreeSet不允许重复元素,并且可以高效地进行插入、删除和查找操作。由于TreeSet是有序的,因此它提供了一些额外的方法,如获取最小元素、获取最大元素、获取小于等于某个值的最大元素等。

1.5.2 练习

源代码: 

package com.zhy.coll;import java.util.TreeSet;public class TestTreeSet {public static void main(String[] args) {TreeSet<Integer> treeSet = new TreeSet<>();treeSet.add(12);treeSet.add(98);treeSet.add(10);System.out.println("初始化treeSet集合:" + treeSet);Integer first = treeSet.first();System.out.println("获取集合中的第一个元素:" + first);Integer integer = treeSet.pollLast();System.out.println("移除集合中的最后一个元素:" + integer);System.out.print("使用增强for遍历集合:");for (Integer i : treeSet){System.out.print(i + " ");}}
}

输出结果: 

1.6 HashSet、LinkedHashSet、TreeSet 的异同点

        HashSet、LinkedHashSet和TreeSet是Java中集合框架中Set集合的三个实现类,它们之间有一些异同点。

数据结构:

  • HashSet是基于哈希表实现的集合,它使用哈希函数来确定元素的存储位置。
  • LinkedHashSet是HashSet的子类,它在哈希表的基础上使用链表来维护元素的插入顺序。
  • TreeSet是基于红黑树实现的集合,它能够自动将元素按照自然顺序或自定义的比较器顺序进行排序。

 插入顺序:

  • HashSet不保证元素的插入顺序,元素在集合中的位置是根据哈希函数计算得到的。
  • LinkedHashSet保持元素的插入顺序,即元素按照插入的顺序进行迭代。
  • TreeSet会根据元素的排序规则对元素进行排序,并且在遍历时按照排序后的顺序进行迭代。

排序: 

  • HashSet和LinkedHashSet不对元素进行排序,元素的顺序是根据哈希函数计算得到的。
  • TreeSet会根据元素的自然顺序或自定义的比较器顺序对元素进行排序。

性能: 

  • HashSet的性能通常比较好,它提供了O(1)的常数时间复杂度的插入、删除和查找操作。
  • LinkedHashSet的插入、删除和查找操作的性能稍微低于HashSet,因为它还需要维护插入顺序。
  • TreeSet提供了O(log n)的时间复杂度的插入、删除和查找操作,它的性能较HashSet和LinkedHashSet要低。

        总而言之,HashSet适用于需要快速插入、删除和查找操作的场景;LinkedHashSet适用于需要保持插入顺序的场景;TreeSet适用于需要对元素进行排序的场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/654581.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【论文复现】

code&#xff1a; paper&#xff1a; 论文 介绍 方法 实验 结论 复现 Image generation 问题1&#xff1a;No models "dcface/dcface/pretrained_models/adaface_ir101_webface4m.ckpt Traceback (most recent call last):File "/data/dcface/dcface/src/r…

如何通俗解释Docker是什么?

要想弄懂Docker&#xff0c;咱们得先从“容器化”讲起。 一、容器化技术及Docker的出现 容器化&#xff0c;它是一种轻量级、可移植的软件打包方式&#xff0c;你就想象成一个快递箱子&#xff0c;里面装着你的应用和所有需要运行的环境&#xff0c;这个箱子能在任何支持容器…

Redisson分布式锁介绍及实战应用(防止缓存击穿)

本地锁 浏览器把100w请求由网关随机往下传&#xff0c;在集群情况下&#xff0c;每台服务都放行10w请求过来&#xff0c;这时候每台服务都用的是本地锁是跨JVM的&#xff0c; 列如这些服务都没有49企业&#xff0c;此时有几个服务进行回原了打击在DB上面&#xff0c;那后期把这…

Blender教程(基础)-物体的移动、旋转与缩放-04

一、新建一个立方体 ShiftA新建一个立方体用来演示。 二、物体的移动 xyz轴移动 点击下图图左侧的移动选项后&#xff0c;选中要移动的物体&#xff0c;会出现三个箭头的方向&#xff0c;这分别代表沿着x、y、z轴移动。xyz平面移动 这个小正方体代表沿着某一个面移动&#…

AWS 专题学习 P14 (Security Encryption)

文章目录 专题总览为什么需要加密&#xff1f;AWS KMS&#xff08;密钥管理服务&#xff09;KMS 密钥类型AWS KMS&#xff08;密钥管理服务&#xff09;Copying Snapshots across regionsKMS Key Policies在不同账户之间复制快照KMS Multi-Region Keys (多区域密钥)DynamoDB 全…

ElasticSearch 学习笔记

基本概念 术语 文档&#xff08;document&#xff09;&#xff1a;每条记录就是一个文档&#xff0c;会以 JSON 格式进行存储 映射&#xff08;mapping&#xff09;&#xff1a;索引中文档字段的约束信息&#xff0c;类似 RDBMS 中的表结构约束&#xff08;schema&#xff09…

在linux上进行编译调试

1.相关疑问 1. 为什么在代码里使用了一个未定义过的函数&#xff08;如add()&#xff09;&#xff0c;在编译阶段不会报错&#xff0c;在链接阶段会报错呢&#xff1f; 答&#xff1a;先说几个代码编译的结论&#xff1a; 单个\.c源文件文件被编译成机器码文件时&#xff0c…

LVS 工作模式

1、LVS DR模式 DR 模式是通过改写请求报文的目标 MAC 地址&#xff0c;将请求发给真实服务器的&#xff0c;而真实服务器响应后的处理结果直接返回给客户端用户。DR 模式可以极大的提高集群系统的伸缩性。但是要求调度器 LB 与真实服务器 RS 都有一块网卡连接到同一物理网段上…

Codeforces Round 785 C. Palindrome Basis

C. Palindrome Basis 题意 定义一个正整数 a a a 是回文的&#xff08;没有前导 0 0 0&#xff09;当且仅当&#xff1a; a a a 的十进制表示形式回文 给定一个正整数 n n n &#xff0c;求出将 n n n 拆分成若干个回文数之和的方案数 思路 这是一个经典模型&#xff0…

媒体邀约:怎么吸引总体目标受众?

新闻媒体影响力日益扩大。不论是公司、机构还是其他&#xff0c;都希望能够通过新闻媒体的曝光来吸引更多总体目标受众。要想真正吸引住总体目标受众并非易事&#xff0c;需要一定的方案和方法。下面我们就深入探究媒体邀约推广的真相&#xff0c;共享怎么吸引总体目标受众的方…

秋招面试—计算机网络安全

2021 计算机网络安全 1.Get 和 Post 的区别 get 用于获取数据&#xff0c;post用于提交数据&#xff1b; get 的缓存保存在浏览器和web服务器日志中&#xff1b; get 使用明文传输&#xff0c;post请求保存在请求体中&#xff1b; get 长度限制在2048以内 2.常见的HTTP请…

Android P 屏保和休眠相关知识

Android P添加屏保功能&#xff0c;如果休眠时间设定大于屏保时间&#xff0c;则先进入屏保&#xff0c;达到休眠时间后再进入休眠 需求&#xff1a; 添加屏幕互保开关&#xff0c;默认关闭。只保留时钟&#xff0c;可设定指针和数字、夜间模式。启用时间改多长时间无操作进入…

###C语言程序设计-----C语言学习(6)#

前言&#xff1a;感谢老铁的浏览&#xff0c;希望老铁可以一键三连加个关注&#xff0c;您的支持和鼓励是我前进的动力&#xff0c;后续会分享更多学习编程的内容。 一. 主干知识的学习 1. while语句 除了for语句以外&#xff0c;while语句也用于实现循环&#xff0c;而且它…

初识elasticsearch

一、了解ES 1.1.elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能&#xff0c;可以帮助我们从海量数据中快速找到需要的内容 例如&#xff1a; 在GitHub搜索代码 在电商网站搜索商品 在百度搜索答案 在打车软件搜索附近的车 …

(七)for循环控制

文章目录 用法while的用法for的用法两者之间的联系可以相互等价用for改写while示例for和while的死循环怎么写for循环见怪不怪表达式1省略第一.三个表达式省略&#xff08;for 改 while&#xff09;全省略即死循环&#xff08;上面已介绍&#xff09; 用法 类比学习while语句 …

MySQL原理(一)架构组成(1)物理文件组成

目录 一、日志文件 1、错误日志 Error Log 1.1、作用&#xff1a; 1.2、开启关闭&#xff1a; 1.3、使用 2、二进制日志 Binary Log & Binary Log Index 2.1、作用&#xff1a; 2.2、开启关闭&#xff1a; 2.3、Binlog还有一些附加选项参数 &#xff08;1&#x…

江科大stm32学习笔记6——GPIO输入准备

一、按键消抖 由于按键内部使用的是机械式弹簧片&#xff0c;所以在按下和松开时会产生5~10ms的抖动&#xff0c;需要通过代码来进行消抖。 二、滤波电容 在电路中&#xff0c;如果见到一端接在电路中&#xff0c;一端接地的电容&#xff0c;则可以考虑它的作用为滤波电容&am…

linux -- 内存管理 -- 页面分配器

linux内存管理 为什么要了解linux内存管理 分配并使用内存&#xff0c;是内核程序与驱动程序中非常重要的一环。内存分配函数都依赖于内核中一个非常复杂而重要的组件 - 内存管理。 linux驱动程序不可避免要与内核中的内存管理模块打交道。 linux内存管理可以总体上分为两大…

MYSQL基本查询(CURD:创建、读取、更新、删除)

文章目录 前言一、Create1.全列插入2.指定列插入3.插入否则更新4.替换 二、Retrieve1.SELECT列2.WHERE条件3.结果排序4.筛选分页结果 三、Update四、Delete1.删除数据2.截断表 五、插入查询结果六、聚合函数 前言 操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型…

Unity中URP下额外灯角度衰减

文章目录 前言一、额外灯中聚光灯的角度衰减二、AngleAttenuation函数的传入参数1、参数&#xff1a;spotDirection.xyz2、_AdditionalLightsSpotDir3、参数&#xff1a;lightDirection4、参数&#xff1a;distanceAndSpotAttenuation.zw5、_AdditionalLightsAttenuation 三、A…