Java集合中Set都有哪些特性?看这篇就够了!

这篇具有很好参考价值的文章主要介绍了Java集合中Set都有哪些特性?看这篇就够了!。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文将为大家详细讲解Java中的<SET集合>,这是我们进行开发时经常用到的知识点,也是大家在学习Java中很重要的一个知识点,更是我们在面试时有可能会问到的问题。

文章较长,干货满满,建议大家收藏慢慢学习。文末有本文重点总结,主页有全系列文章分享。技术类问题,欢迎大家和我们一起交流讨论!

前言

在上一篇文章中,带大家学习了List集合的用法和特性尤其是对ArrayList和LinkedList了解的更多一些但Java中还有Set和Map集合等待我们学习,所以接下来就请各位继续跟我们一起来学习今天的内容吧。在本文中,会详细地给大家介绍Set集合的定义、特点、常用方法和基本原理等内容。

全文大约【4000】 字,不说废话,只讲可以让你学到技术、明白原理的纯干货!本文带有丰富的案例及配图视频,让你更好地理解和运用文中的技术概念,并可以给你带来具有足够启迪的思考......

一. Set集合简介

Java集合中Set都有哪些特性?看这篇就够了!

1. Set定义

Set是Java的一种集合,继承自Collection接口,主要有两个常用的实现类HashSet类和TreeSet类。它没有固定的大小限制,可以动态地添加和删除元素。并且Set集合中的元素都是唯一的,不会有重复的元素,即使是null值也只能有一个。另外Set集合是无序的,不能记住元素的添加顺序,因为没有索引值,所以Set集合中的对象不会按特定的方式排序,它只是简单地把对象放到集合中。

从特性上来看,Set相当于是一个只存储key、不存储value的Map。我们可以把Set想象成是一个”特殊的Map“,这个Map只有key却没有value,所以我们可以用Set去除重复的元素。另外由于放入Set的元素和Map的key类似,需要正确地实现equals()和hashCode()方法,否则该元素就无法正确地放入Set。

2. Set特性

与其他集合不同,Set集合具有自己的一些特性:

  • Set集合中的元素都是唯一的,不允许有重复值,且最多只允许包含一个null元素;
  • Set集合中的元素没有顺序,我们无法通过索引来访问元素,但TreeSet是有序的;
  • Set集合没有固定的大小限制,可以动态地添加和删除元素;
  • Set集合提供了高效的元素查找和判断方法。

3. Set常用方法

Set集合给我们提供了一系列常用的方法,用于添加、删除、查找、遍历和获取集合元素等操作,下面是Set集合中常用方法的实现过程。

3.1 添加元素

我们可以使用add()方法进行元素的添加。

public boolean add(E e)

该方法用于向Set集合添加元素,如果元素已经存在,则不会添加;如果添加成功,则返回true,否则返回false。该方法的示例代码如下:


Set<String> set = new HashSet<>();

set.add("hello word");

set.add("java");

set.add("iOS");

System.out.println(set);

3.2 删除元素

我们可以使用remove()方法进行元素的删除。

public boolean remove(Object o)

该方法用于从Set集合中删除指定的元素。如果元素存在且删除成功,则返回true,否则返回false。该方法的示例代码如下:

Set<String> set = new HashSet<>(); 
set.add("hello word"); 
set.add("java"); 
set.remove("java"); 
System.out.println(set); // 输出结果为:[壹壹哥]

3.3 判断元素

我们可以使用contains()方法进行元素的判断。

public boolean contains(Object o)

该方法用于判断Set集合中是否包含指定的元素。如果元素存在,则返回true,否则返回false。该方法的示例代码如下:

Set<String> set = new HashSet<>(); 
set.add("hello word"); 
set.add("java");
System.out.println(set.contains("java")); // 输出结果为:true 
System.out.println(set.contains("orange")); // 输出结果为:false

3.4 获取元素数量

我们可以使用size()方法判断集合的数量。

public int size()

该方法的使用示例代码如下:

Set<String> set = new HashSet<>(); 
set.add("hello word"); 
set.add("java"); 
System.out.println(set.size()); // 输出结果为:2

4. 配套视频

与本节内容配套的视频链接如下:戳链接一键直达

二. HashSet集合

1. 简介

在Java的集合框架中,HashSet是一种非常常用的集合类型,它实现了Set接口,并继承了AbstractSet抽象类。HashSet集合的底层实现是一个哈希表,它使用哈希算法来存储和管理集合中的元素。HashSet集合中的元素没有顺序,且不允许重复。

如果我们想使用HashSet集合,一般要使用如下两个构造方法创建出HashSet对象:

  • HashSet() :构造一个新的空的Set集合对象;
  • HashSet(Collection<? extends E> c) :构造一个包含指定Collection集合元素的新Set集合。"< >"中的extends,表示这个Collection中的元素必须继承自HashSet的父类,该部分限定了Collection元素的类型。

2. HashSet特性

HashSet作为Set集合的具体子类,具有以下特点:

HashSet的底层是基于HashMap来实现的;

HashSet中的元素是唯一的,内部不允许有重复的元素;

无序,不会记录插入元素的顺序,所以不能保证元素的排列顺序,获取顺序可能与添加顺序不同;

HashSet集合没有固定的大小限制,可以动态地添加和删除元素;

HashSet集合中的元素最多可以有一个null值;

HashSet不是线程安全的,默认线程不同步,如果有多个线程同时访问或修改同一个HashSet,必须通过代码来保证同步操作。

3. 去重原理

从底层实现来看,HashSet的底层其实就是一个值为Object的HashMap,如下图所示:

Java集合中Set都有哪些特性?看这篇就够了!

Java集合中Set都有哪些特性?看这篇就够了!

所以HashSet其实就是按照Hash算法来实现元素的查找和存储的,具有很好的存取和查找性能。当我们向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该hashCode值决定该对象在HashSet中的存储位置。此时如果有两个元素通过equals()方法进行比较,返回的结果为true,但它们的hashCode却不相等,HashSet也会把它们存储在不同的位置,我们依然可以添加成功。也就是说,如果两个对象的hashCode值相等,且通过equals()方法比较返回的结果也为true, HashSet集合才会认为两个元素相等

与本节内容配套的视频链接如下: https://www.bilibili.com/video/BV1Ja411x7XB?t=0.0

4. 使用案例

我们通过一个简单的案例,来看看HashSet的基本用法。

import java.util.HashSet;

/**
 * @author 一一哥Sun
 */
public class Demo11 {

	public static void main(String[] args) {
		//创建HashSet集合
		HashSet<String> set = new HashSet<String>();
		set.add("一一哥");
		set.add("壹壹哥");
		set.add("java");
		//重复元素无法被添加进去
		set.add("java");
		System.out.println(set);

        //集合遍历
		Iterator<String> it = set.iterator();
	    while (it.hasNext()) {
	    	//输出Set集合中的每个元素
	        System.out.println("值="+it.next()); 
	    }
	}
}

在上面的代码中,我们通过HashSet的构造方法创建了一个Set集合对象,并将几个元素对象存储到了这个Set集合中。

然后我们使用HashSet类中的iterator()方法获取一个Iterator对象,并调用hasNext()方法遍历集合元素,再使用next()方法获取到下一个数据元素。但是HashSet输出的元素是无序的,输出时既不是添加元素的顺序,也不是String排序的顺序,在不同版本的JDK中,这个顺序可能也是不同的。另外因为Set是不可重复的,如果我们向Set集合中添加了两个相同的元素,则后添加的会覆盖前面添加的元素,所以Set集合中不会出现相同的元素。

5. 配套视频

与本节内容配套的视频链接如下:戳链接一键直达

三. TreeSet集合

1. 简介

TreeSet是一种很常用的集合类型,它实现了Set和SortedSet接口,并且继承自AbstractSet抽象类。TreeSet集合中的元素也是唯一的,不允许重复。TreeSet集合的底层基于红黑树,可以使用自然排序或指定的比较器对集合中的元素进行排序。该类具有如下特点:

  • TreeSet集合中的元素是唯一的,不允许重复。
  • TreeSet集合中的元素是有序的, 因为实现了 SortedSet 接口 ,具有字典顺序, 可以通过迭代器按照升序或降序遍历。
  • TreeSet集合没有固定的大小限制,可以动态地添加和删除元素。
  • TreeSet集合提供了高效的元素查找和判断功能。

另外,SortedSet接口是Set接口的子接口,能够对集合进行自然排序,因此TreeSet类默认情况下就是自然排序(升序)的。但TreeSet只能对实现了Comparable接口的类对象进行排序,所以我们使用TreeSet集合存储对象时,该对象必须要实现Comparable接口。这是因为Comparable接口中有一个compareTo(Object o)方法,可以比较两个对象的大小。例如,a.compareTo(b),如果 a 和 b 相等,则该方法会返回 0;如果 a 大于 b,则该方法返回大于 0 的正值;如果 a 小于 b,则该方法返回小于 0 的负值。

2. 常用方法

除了Set类中通用的方法之外,TreeSet类还有如下几个特有的方法:

方法名称 说明
E first() 返回该集合中的第一个元素,E表示返回元素的数据类型
E last() 返回该集合中的最后一个元素
E poolFirst() 获取并移除该集合中的第一个元素
E poolLast() 获取并移除该集合中的最后一个元素
SortedSet subSet(E fromElement,E toElement) 返回一个新的集合,新集合会包含源集合fromElement与目标集合toElement之间的所有对象。结果会包含fromElement对象,但不包含toElement对象。
SortedSet headSet<E toElement〉 返回一个新的集合,新集合包含原集合中toElement对象之前的所有对象,但不包含 toElement对象。
SortedSet tailSet(E fromElement) 返回一个新的集合,新集合包含原集合中fromElement对象之后的所有对象,会包含fromElement对象。

因为TreeSet中的元素是有序的,所以增加了访问第一个、前一个、后一个、最后一个元素的相关方法,并提供了3个从 TreeSet中截取子TreeSet的方法。

3. 去重原理

当TreeSet集合在保存对象元素时,集合对象必须实现Comparable接口,并重写compareTo方法,该方法有如下两个作用:

  • 排序: 返回值大于0表示升序,返回值小于0表示降序;
  • 去重(返回值为0) :TreeSet认为返回0,表示两个对象是相同的对象。

所以我们利用TreeSet实现去重的原理就是:如果compareTo()方法的返回值为0,则认为是相同的对象;如果compareTo()方法的返回大于0,则是升序排序;如果小于0,则是降序排序。

4. 使用案例

接下来我们再通过一个案例来看看TreeSet的用法。

4.1 编写Person类

首先我们设计一个Person类,该类要实现Comparable接口。当TreeSet集合在保存对象元素时,集合中添加的元素对象必须实现Comparable接口,并重写compareTo方法。如果没有实现Comparable接口,那么创建TreeSet时必须传入一个Comparator对象。

/**
 * @author 一一哥Sun
 * 实现Comparable接口,并重新compareTo()方法
 */
public class Person implements Comparable<Person>{

	private String username;
    private String password;
    
    public Person() {
    }
    
    public Person(String username, String password) {
        super();
        this.username = username;
        this.password = password;
    }
    
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }

    //重写compareTo()方法,对Person对象进行比较
    @Override
    public int compareTo(Person o) {
        if(!this.username.equals(o.username)) {
        	//根据姓名及长度进行比较
            return this.username.length() - o.username.length();
        }else {
        	//根据密码进行比较
            if(this.password.equals(o.password)) {
                return 0;
            }else {
            	//比较姓名的长度
                return this.username.length() - o.username.length();
            }
        }
    }
}

与本节内容配套的视频链接如下:戳链接一键直达

4.2 测试TreeSet排序功能

然后我们往TreeSet集合中添加若干个对象元素进行排序测试,代码如下:

import java.util.TreeSet;

/**
 * @author 一一哥Sun
 */
public class Demo12 {

	public static void main(String[] args) {
		//TreeSet的去重原理
        TreeSet<Person> set = new TreeSet<Person>();
        set.add(new Person("admin","123"));
        set.add(new Person("yyg","bb"));
        set.add(new Person("jack","123"));
        set.add(new Person("rose123","123"));
        set.add(new Person("admin","123")); 
        set.add(new Person("xksss6","abc"));

        //如果两个对象的用户名和密码都相等,则认为是两个相同的对象,且按照名字长度升序存放
        for (Person person : set) {
            System.out.println(person);
        }
	}
}

我们在遍历TreeSet时,输出的元素是有序的,这个顺序是元素的排序顺序。但是我们在使用TreeSet进行自然排序时,只能向 TreeSet 集合中添加相同数据类型的对象,否则会抛出 ClassCastException异常。如果向 TreeSet集合中添加了一个 Double类型的对象,则后面只能添加 Double对象,不能再添加其他类型的对象,例如 String对象等。

5. 配套视频

与本节内容配套的视频链接如下:戳视频一键直达


四. 结语

至此,我们就带各位把Set集合及其子类学习完了,现在你学会了吗?本文的重点内容如下所示:

Set用于存储不重复的元素集合;

放入HashSet的元素,与作为HashMap的key要求相同;

放入TreeSet的元素,与作为TreeMap的Key要求相同;

利用Set可以去除重复元素;

遍历SortedSet时,可以按照元素的排序顺序进行遍历,我们也可以自定义排序算法;文章来源地址https://www.toymoban.com/news/detail-454445.html


到了这里,关于Java集合中Set都有哪些特性?看这篇就够了!的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 从Java BIO到NIO再到多路复用,看这篇就够了

    目录 从一次优化说起 IO模型分类 分类 举例 概念详解 阻塞和非阻塞 同步与异步 Java支持版本 实战 c10k问题 上代码 BIO服务端 NIO服务端​​​​​​​ 多路复用 概念 阶段一:selectpoll 阶段二epoll Java selector 后记         近期优化了一个老的网关系统,在dubbo调用接口rt100

    2024年02月08日
    浏览(44)
  • JAVA JDK最详细的安装教程--你只需要看这篇就够了

    熟练的配置开发环境是每一个程序员必备的功课,俗话说: 工欲善其事,必先利其器 。 注:本文安装的是J AVA JDK 1.8-8u 321 window64位版本,软件获取链接如下(阿里云盘) 阿里云盘分享 提取码: cn24 第一步,安装J DK: 自定义安装路径 jdk1.8安装会安装jdk、jre , 所以需要新建两个

    2023年04月08日
    浏览(37)
  • Linux,看这篇就够了

    因为我们要部署服务,Linux系统一直以其稳定性而闻名,它们可以连续运行多年而不发生任何重大问题。事实上,很多Linux用户都从未在自己的环境中遇到过系统崩溃的情况。相对windows而言,挂起和崩溃完全是一种常态。 Windows由于是商业产品,源代码封闭,我们无法知道微软

    2024年02月08日
    浏览(43)
  • 测试基本理论-看这篇就够了

    软件测试(Software Testing): 在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。 【系统软件】:如操作系统、数据库管理系统,各种驱动软件等; 【应用软件】:如Office、有道翻译、QQ等; 【单机版本】:如Office,

    2024年02月06日
    浏览(47)
  • 面向对象编程,看这篇就够了

    面向对象编程,是一种程序设计范式,也是一种编程语言的分类。它以对象作为程序的基本单元,将算法和数据封装其中,程序可以访问和修改对象关联的数据。这就像我们在真实世界中操作各种物体一样,比如我们可以打开电视、调整音量、切换频道,而不需要知道电视的

    2024年02月05日
    浏览(76)
  • 关于SpringBoot框架,看这篇就够了。

    目录 是什么 有什么优点、解决了哪些问题 创建第一个以springboot项目 starter 核心配置文件application.yml或properties application中的配置项 springboot的启动流程 自定义banner 整合日志打印 整合druid数据源 处理异常 常用的注解 Configuration Import conditional ConfigruationProperties 基于springboot的

    2024年02月06日
    浏览(47)
  • Redis基础命令汇总,看这篇就够了

    本文首发于公众号:Hunter后端 原文链:Redis基础命令汇总,看这篇就够了 本篇笔记将汇总 Redis 基础命令,包括几个常用的通用命令,和各个类型的数据的操作,包括字符串、哈希、列表、集合、有序集合等在内的基本操作。 以下是本篇笔记目录: 通用命令 字符串命令 哈希

    2024年02月04日
    浏览(47)
  • 倾向得分匹配只看这篇就够了

    倾向得分匹配模型是由Rosenbaum和Rubin在1983年提出的,首次运用在生物医药领域,后来被广泛运用在药物治疗、计量研究、政策实施评价等领域。倾向得分匹配模型主要用来解决非处理因素(干扰因素)的偏差。 ‍1、基本原理——反事实推断 基本原理是 :根据处理组的特征,

    2024年02月05日
    浏览(44)
  • TensorBoard最全使用教程:看这篇就够了

    机器学习通常涉及在训练期间可视化和度量模型的性能。 有许多工具可用于此任务。 在本文中,我们将重点介绍 TensorFlow 的开源工具套件,称为 TensorBoard,虽然他是TensorFlow 的一部分,但是可以独立安装,并且服务于Pytorch等其他的框架。 TensorBoard 是一组用于数据可视化的工

    2024年01月17日
    浏览(47)
  • ElasticSearch自定义评分-看这篇就够了

    文章目录   一、适用的场景    1.基本介绍    2.使用场景     2.1根据价格评分排序     2.2根据距离评分排序     2.3根据距离价格综合评分排序     2.4自定义编写脚本   二、常用的字段解释    1.整体结构    2.function_score     2.1.qu

    2024年02月06日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包