第7章-第4节-Java中的Set集合和自然排序compareble

1、HashSet:

1)、 Set集合的特点

  • 元素存储可以有序,可以无序(要看选择的具体子类 HashSet 无序 LinkedHashSet(有序),TreeSet(排序))

  • 没有索引,不能通过索引获取元素(即也不能使用普通for循环遍历)

  • 不可以存储重复的元素

    在某一些特定的场景,我们想要实现不能保存重复的元素的效果,此时使用Set集合就非常的合适

2)、 概述及特点

概述:HashSet集合是Set集合的子类,是一个具体的类。底层使用Hash表存储数据(hash本质就是一个数组)。HashSet存储数据使用的是HashMap的key部 分(HashMap我们明天会学习到,是一个双列的存储数据的结构)

存储数据的结构:数组 + 链表 + 红黑树

特点

  • 元素存储无序

  • 没有索引,不能通过索引获取元素(即也不能使用普通for循环遍历)

  • 不可以存储重复的元素

3)、 常用方法 

1>、增加:

import java.util.HashSet;
import java.util.Set;public class AddDemo {public static void main(String[] args) {Set<Integer> set = new HashSet<>();// 添加元素set.add(1);set.add(2);set.add(3);set.add(17);System.out.println(set);Set<String> set2 = new HashSet<>();// 添加元素set2.add("zhangsan");set2.add("lisi");set2.add("wangwu");set2.add("zhaoliu");set2.add(null);// 允许添加null值,但是只能添加一次System.out.println(set2);}
}

2>、删除:

import java.util.HashSet;
import java.util.Set;public class RemoveDemo {public static void main(String[] args) {Set<String> set = new HashSet<>();// 添加元素set.add("zhangsan");set.add("lisi");set.add("wangwu");set.add("zhaoliu");System.out.println(set);// 删除元素boolean flag = set.remove("zhangsan");System.out.println(flag);System.out.println(set);System.out.println("-----优雅的分隔符-----");// 删除部分元素Set<String> set2 = new HashSet<>();set2.add("lisi");set2.add("zhaoliu");set2.add("zhangsan");boolean result = set.removeAll(set2);System.out.println(result);System.out.println(set);// 清空集合set.removeAll(set);System.out.println(set);set.clear();System.out.println(set);}
}

3>、修改:

import java.util.HashSet;
import java.util.Set;public class UpdateDemo {public static void main(String[] args) {Set<String> set = new HashSet<>();// 添加元素set.add("zhangsan");set.add("lisi");set.add("wangwu");set.add("zhaoliu");System.out.println(set);// 没有修改的方法}
}

4>、查询:

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;public class SelectDemo {public static void main(String[] args) {Set<String> set = new HashSet<>();// 添加元素set.add("zhangsan");set.add("lisi");set.add("wangwu");set.add("zhaoliu");System.out.println(set);// 获取集合的长度System.out.println(set.size());// 查询是否包含某一个指定的值boolean flag = set.contains("zhangsan");System.out.println(flag);// 集合是否为空System.out.println(set.isEmpty());// 增强for循环for(String str : set) {System.out.println(str);}System.out.println("----------------------");// 迭代器Iterator<String> iterator = set.iterator();while(iterator.hasNext()){String value = iterator.next();System.out.println(value);}}
}

4)、底层原理图:

备注:它的底层是用HashMap实现的, HashMap也是类似原理,后面章节会更具体的讲解HashMap。

2、TreeSet:

1)、学习了hashSet,无序不可重复。但是,有些时候,某些场景还是需要按照指定要求对数据进行排序。也就是说,要求我们的数据有序(此处 的有序指的不是存入顺序与取出顺序一致,而是按照指定的规则从大到小或者从小到大排序),比如,在录入学生考试成绩的时候 ,我就希望能够按照绩来进行排序。

很显然,这个功能使用HashSet没有办法实现,所以,我们需要学习TreeSet树结构,二叉树

2)、 概述及特点

概述:TreeSet实现了Set接口,存储的元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法。

  • TreeSet():根据其元素的自然排序进行排序

  • TreeSet(Comparator comparator) :根据指定的比较器进行排序

    特点

  • 存储的元素有序

  • 没有带索引的方法,所以不能使用普通for循环遍历

  • 由于是Set集合,所以不包含重复元素的集合

    数据结构:采用的是红黑树的结构(本质上使用的是TreeMap的key部分)

    常用的方法与HashSet一致,这里不在进行演示,主要是讲解其排序的特点

3) 、保存基本数据类型及字符串

 1>、保存基本数据类型

import java.util.Set;
import java.util.TreeSet;public class TreeSetDemo01 {public static void main(String[] args) {Set<Integer> set = new TreeSet<>();set.add(5);set.add(4);set.add(2);set.add(1);set.add(3);set.add(3);// 不能保存重复的元素System.out.println(set);// 保存的元素有序}
}

2>、保存字符串类型

import java.util.Set;
import java.util.TreeSet;public class TreeSetDemo02 {public static void main(String[] args) {Set<String> set = new TreeSet<>();set.add("zhangsan");set.add("lisi");set.add("wangwu");set.add("zhaoliu");set.add("zhouqi");set.add("wangba");set.add("zhousan");// 不能存储重复的元素System.out.println(set);// 保存的元素有序}
}

3>、保存自定义类型

public class Student {private String name;private Integer age;public Student() {}public Student(String name, Integer age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}
}
import java.util.Set;
import java.util.TreeSet;public class TreeSetDemo03 {public static void main(String[] args) {Set<Student> set = new TreeSet<>();set.add(new Student("zhangsan", 21));set.add(new Student("lisi", 19));set.add(new Student("wangwu", 18));set.add(new Student("wangba", 23));System.out.println(set);// 保存的元素有序}
}

异常为:java.lang.ClassCastException: com.woniu.treeset.Student cannot be cast to java.lang.Comparable。

类型转换异常,说是Student 不能 转换为 Comparable。Comparable在我们的代码里面没有涉及到,为什么会出现这个问题呢?Integer,String也是引用类型,我们在使用的时候没有出现这异常呢。

所以,我们来看一下String的源码

 3、自然排序compareble:

comparable : 自然排序。是一个接口,只提供了一个方法:compareTo。就是排序的比较规则。如果使用TreeSet的无参构造方法保存自定义数据类型,那么该类应该实现comparable 接口,重写compareTo方法

public interface Comparable<T> {// 返回值为0,表示两个元素相等// 返回值为正整数,表示大于// 返回值为负整数,表示小于public int compareTo(T o);
}

案例演示

需求:存储学生对象并遍历,创建TreeSet集合使用无参构造方法。

要求:按照年龄从小到大排序。

public class Student implements Comparable<Student>{private String name;private Integer age;public Student() {}public Student(String name, Integer age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int compareTo(Student stu) {// 排序的规则// this表示需要添加进来的元素 --->         set.add(new Student("lisi", 19));  表示的是lisi// stu表示需要比较的对象,即已经存进集合里面的对象//System.out.println(stu.age + "---" + this.age);return this.age - stu.age;}
}
import java.util.Set;
import java.util.TreeSet;public class TreeSetDemo03 {public static void main(String[] args) {Set<Student> set = new TreeSet<>();set.add(new Student("zhangsan", 21));set.add(new Student("lisi", 19));set.add(new Student("wangwu", 18));set.add(new Student("wangba", 23));set.add(new Student("zhouqi", 21));System.out.println(set);// 保存的元素有序}
}

本电子书目录:《Java基础的重点知识点全集》

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

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

相关文章

学生成绩录入及查询(结构体)

学生成绩表中&#xff0c;一名学生的信息包含如下信息&#xff1a; 学号(11位)、姓名、数学成绩、英语成绩、程序设计成绩、物理成绩。 本题要求编写程序&#xff0c;录入N条学生的信息&#xff0c;并且按查询要求显示学生成绩等信息。 输入格式: 输入在第一行给出正整数N(N…

Java学习网站,哪个最靠谱?

简介 Java学习网站有很多&#xff0c;哪个最靠谱呢&#xff1f;本文对Java学习网站进行对比。 第1类&#xff1a;大型培训机构(黑马等) 典型机构 黑马、尚硅谷、动力节点、白马、千锋、达内。 优点 知名度高。教程齐全&#xff08;Java、前端、Python等都有&#xff09;省…

PiflowX组件-ReadFromUpsertKafka

ReadFromUpsertKafka组件 组件说明 upsert方式从Kafka topic中读取数据。 计算引擎 flink 有界性 Unbounded 组件分组 kafka 端口 Inport&#xff1a;默认端口 outport&#xff1a;默认端口 组件属性 名称展示名称默认值允许值是否必填描述例子kafka_hostKAFKA_HO…

AI看图识熊实战(一)

使用ONNX Runtime封装onnx模型并推理 进行这一步之前&#xff0c;请确保已正确安装配置了Visual Studio 2017 和 C#开发环境。 项目的代码也可以在这里找到&#xff0c;下面的步骤是带着大家从头到尾做一遍。 界面设计 创建Windows窗体应用(.NET Framework)项目&#xff0c…

c# 学习笔记 - 枚举

文章目录 1. 枚举1.1 枚举结构梳理1.2 枚举完整代码1.3 枚举知识点补充 2. 迭代两种命名空间接口3. yield语句 1. 枚举 1.1 枚举结构梳理 结构图   上图内容可能依旧不通俗易懂&#xff0c;这里使用最简明的话语告诉大家实现方式. foreach语句就是集合的遍历操作&#xff0c…

221.【2023年华为OD机试真题(C卷)】字符串变换最小字符串(贪心策略-JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目二.解题思路三.题解代码Python题解代码JAVA题解…

2024.1.3力扣每日一题——从链表中移除节点

2024.1.3 题目来源我的题解方法一 递归方法二 栈方法三 反转链表方法四 单调栈头插法 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2487 我的题解 方法一 递归 当前节点对其右侧节点是否删除无影响&#xff0c;因此可以对其右侧节点进行递归移除。 若当前节点为空&am…

快速掌握Postman实现接口测试

快速掌握Postman实现接口测试 Postman简介 Postman是谷歌开发的一款网页调试和接口测试工具&#xff0c;能够发送任何类型的http请求&#xff0c;支持GET/PUT/POST/DELETE等方法。Postman非常简单易用&#xff0c;可以直接填写URL&#xff0c;header&#xff0c;body等就可以发…

Unity2D学习笔记 | 《勇士传说》教程 | (六)

目录 &#xff08;一&#xff09;存档点对象制作 &#xff08;二&#xff09;保存数据与加载数据 &#xff08;三&#xff09;存储数值与场景 &#xff08;四&#xff09;游戏结束画面制作 &#xff08;五&#xff09;序列化数据保存 &#xff08;一&#xff09;存档点对象…

Java多线程技术11——ThreadPoolExecutor类的使用2

1 isShutdown()方法 public boolean isShutdown()方法的作用是判断线程池是否已经关闭 public class Run1 {public static void main(String[] args) {Runnable runnable new Runnable() {Overridepublic void run() {try {System.out.println("开始: " Thread.c…

软件安装文档 | MinIO

# docker 下载镜像 docker pull minio/minio# 安装镜像docker run \ --name minio \ -p 19000:9000 \ -p 19090:9090 \ -d --restartalways \ -e "MINIO_ROOT_USERsuweijie" \ -e "MINIO_ROOT_PASSWORDSuweijie0217" \ -v /home/data:/data \ -v /home/c…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第三天-Linux进程练习题(物联技术666)

更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。 物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件,单片机…

优化|PLSA理论与实践

PLSA又称为概率潜在语义分析&#xff0c;是一种利用概率生成模型对文本集合进行话题分析的无监督学习方法。该模型最大的特点是加入了主题这一隐变量&#xff0c;文本生成主题&#xff0c;主题生成单词&#xff0c;从而得到单词-文本共现矩阵。本文将对包含物理学、计算机科学、…

学习笔记——C++中的循环结构 while语句

while循环语句 作用&#xff1a;满足循环条件&#xff0c;执行循环语句 语法&#xff1a;while&#xff08;循环条件&#xff09;{循环语句} 解释&#xff1a;只要循环条件的结果为真&#xff0c;就执行循环语句 以打印0-9这十个数字为例&#xff0c;特别需要注意的是&…

Anaconda安装失败及解决办法

查看Anaconda版本时正常显示 报错显示&#xff1a; 解决办法&#xff1a; 确保系统要求满足&#xff1a;检查你的操作系统是否满足 Anaconda 的最低要求。例如&#xff0c;确保你使用的是 64 位操作系统&#xff0c;同时具备足够的磁盘空间。禁用防病毒软件&#xff1a;某些防…

单片机原理及应用:独立式键盘控制LED与多功能按键识别

今天来介绍另一个外设——按键与LED的配合工作&#xff0c;与开关不同&#xff0c;按键需要注意消除抖动带来的影响&#xff0c;代码逻辑也会更复杂一写&#xff0c;下面先为大家介绍独立式键盘的相关知识。 单片机的独立式键盘指的是一种不依赖于计算机或其他外部设备的键盘输…

【STM32学习】硬件CRC与传统CRC-32计算的不同点

硬件CRC与传统CRC-32计算的不同点 1、stm32的硬件CRC32与传统CRC-32有何不同&#xff1f;2、解决办法 1、stm32的硬件CRC32与传统CRC-32有何不同&#xff1f; ①STM32F103的硬件CRC校验是对整个32位字进行CRC计算&#xff0c;传统的CRC-32是逐字节的计算。 ②STM32的硬件CRC32的…

基于SSM的校内信息服务发布系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

Redis高并发高可用(集群)

Redis Cluster是Redis的分布式解决方案,在3.0版本正式推出,有效地解决了Redis分布式方面的需求。当遇到单机内存、并发、流量等瓶颈时,可以采用Cluster架构方案达到负载均衡的目的。之前,Redis分布式方案一般有两种: 1、客户端分区方案,优点是分区逻辑可控,缺点是需要自己…

初识动态内存管理

前言&#xff1a; 我们都知道&#xff0c;内存分为几个区——栈区、堆区、静态区、常量区、代码区&#xff0c;我们在写代码的时候经常会遇到栈溢出这个问题&#xff0c;是因为在程序运行之前&#xff0c;我们无法准确的知道要分配多少空间给程序&#xff0c;所以说很容易造…