集合框架和泛型二
一、Set
接口
1. Set接口概述
java.util.Set
不包含重复元素的集合、不能保证存储的顺序、只允许有一个 null
。
public interface Set<E>
extends Collection<E>
抽象方法,都是继承自 java.util.Collection
接口。
Set
集合的实现类有很多,在此我们重点了解 HashSet
、 TreeSet
、 LinkedHashSet
。
不允许使用索引:Set
集合中没有提供使用索引来访问元素的方法,因为元素没有固定的顺序。
非同步:不是线程安全的。
HashSet
:基于哈希表实现,具有O(1)的平均时间复杂度的查找、插入和删除操作。
TreeSet
:基于红黑树实现,具有排序功能,元素会按照自然排序或指定的比较器顺序进行排序。
LinkedHashSet
:基于哈希表和链表实现,保留元素的插入顺序,具有O(1)的平均时间复杂度的查找、插入和删除操作。
2.HashSet
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, Serializable
实现了 Set
接口,底层实现是 HashMap
。不保证迭代顺序,允许 null
元素。
- 非线程安全的
- 如果 add 的值已存在( equals 方法返回 true ,基本数据类型自动装箱)返回 false
- 如果 HashSet 中存的是对象,需要重写此对象类中的 equals 和 hashCode() 方法
HashSet集合的特点:
(1)元素唯一性:不允许重复的元素。每个元素只能存在一次。
(2)无序性
(3)基于哈希表
(4)非同步
(5)只能存在一个null元素
HashSet() | 构造一个新的空集合; 底层实现HashMap实例具有默认初始容量(16)和负载因子(0.75)。 |
---|---|
HashSet(Collection<?extends E> c) | 构造一个包含指定集合中的元素的新集合 |
HashSet(int initialCapacity) | 构造一个新的空集合,默认初始容量(initialCapacity)和负载因子(0.75) |
HashSet(int initialCapacity, float loadFactor) | 构造一个新的空集合; 底层HashMap实例具有指定的初始容量和指定的负载因子 |
3.TreeSet
public class TreeSet<E>
extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, Serializable
- 非线程安全
- 值必须可比较(元素实现 Comparable 接口、传递 比较器 Comparator 对象)
- 不能存 null
- 判断是否是重复元素,是按照自然比较/比较器进行比较
就是说a.compareTo(b) == 0,如果是 true ,那么 add(a) 之后的 add(b) 将会返回 false ,也就是添加失败。
ceiling(E e) | E | 返回此集合中大于或等于给定元素的最小元素,如果没有这样的元素,则返回null。 |
---|---|---|
floor(E e) | E | 返回此集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回null。 |
– | – | – |
headSet(E toElement) | SortedSet<[E]> | 返回此集合中元素严格小于toElement的部分的视图。 |
– | – | – |
tailSet(E fromElement) | SortedSet<[E]> | 返回此集合中元素严格大于或等于fromElement的部分的视图。 |
– | – | – |
higher(e) | E | 返回此集合中严格大于给定元素的最小元素,如果没有这样的元素,则返回null |
– | – | – |
higher(e) | lower(e) | 返回此集合中严格小于给定元素的最大元素,如果没有这样的元素,则返回null。 |
TreeSet<String> set = new TreeSet(List.of("null", "a", "a", "b", "c", "e", "f",
"g"));
System.out.println(set); // [a, b, c, e, f, g, null]
// 返回此集合中大于或等于给定元素的最小元素,如果没有这样的元素,则返回null。
String ceiling = set.ceiling("d");
System.out.println(ceiling);// e
// 返回当前在此集合中的第一个(最低的)元素。
String first = set.first();
System.out.println(first); // a
// 返回此集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回null。
String floor = set.floor("d");
System.out.println(floor); // c
// 返回此集合中元素严格小于toElement的部分的视图。
SortedSet<String> headSet = set.headSet("c");
System.out.println(headSet); // a, b
// 返回此集合中严格大于给定元素的最小元素,如果没有这样的元素,则返回null。
String higher = set.higher("c");
System.out.println(higher); // e
// 返回此集合中元素严格大于或等于fromElement的部分的视图。
SortedSet<String> tailSet = set.tailSet("c");
System.out.println(tailSet); // c, e, f, g, null
// 迭代
for (Object obj : set){
System.out.println(obj);
}
4.LinkedHashSet
public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable
- 哈希表和双向链表实现的 Set 接口
- 具有可预测的迭代次序(有序)
- 内部实现是 LinkedHashMap ,顺序是插入顺序
二、Iterator
接口
1.Iterator接口
概述
Iterator接口表示对集合进行迭代的迭代器。Iterator接口为集合而生,专门实现集合的遍历。主要有两个方法:
- hasNext():判断是否存在下一个可以访问的元素,有返回true。
- next():返回要访问的下一个元素。
由Collection接口派生的类或接口,都实现了iterator()方法,iterator()方法返回一个Iterator对象。
2.使用Iterator遍历集合
package collection;import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;/*** 创建一个Map,完成以下操作:* 将我国省份和其简称存到 Map 集合中* 将省份名称中包含"江"的省份从集合中删除* 遍历输出集合元素*/
public class Basic {public static void main(String[] args) {Map<String,String> map=new HashMap();map.put("北京", "京");map.put("上海", "沪");map.put("天津", "津");map.put("重庆", "渝");map.put("河北", "冀");map.put("山西", "晋");map.put("辽宁", "辽");map.put("吉林", "吉");map.put("黑龙江", "黑");map.put("江苏", "苏");map.put("浙江", "浙");map.put("安徽", "皖");map.put("福建", "闽");map.put("江西", "赣");map.put("山东", "鲁");map.put("河南", "豫");map.put("湖北", "鄂");map.put("湖南", "湘");map.put("广东", "粤");map.put("海南", "琼");map.put("四川", "川");map.put("贵州", "黔");map.put("云南", "滇");map.put("陕西", "陕");map.put("甘肃", "甘");map.put("青海", "青");map.put("台湾", "台");map.put("内蒙古", "蒙");map.put("广西", "桂");map.put("西藏", "藏");map.put("宁夏", "宁");map.put("新疆", "新");map.put("香港", "港");map.put("澳门", "澳");System.out.println(map.size());//将省份名称中包含"江"的省份从集合中删除Set<Map.Entry<String, String>> entries = map.entrySet();Iterator<Map.Entry<String, String>> iterator = entries.iterator();while (iterator.hasNext()){Map.Entry<String, String> next = iterator.next();if (next.getKey().contains("江")){iterator.remove();}}//遍历for (String key:map.keySet()) {System.out.println(key);}System.out.println(map.size());}
}
三、Map
接口
Map
接口不是 Collection
的子接口,使用键、值映射表来存储。
public interface Map<K,V>
- Map 不能有重复的键(覆盖),每个键可以映射到最多一个值
- 允许将映射内容视为一组键、值集合或键值映射集合
- key 不要求有序,不可以重复。 value 也不要求有序,但可以重复
- 当使用对象作为 key 时,要重写 equals 和 hashCode 方法
`JDK9` 提供了创建不可修改 Map 对象的方法:
1. Map.of
2. Map.ofEntries
3. Map.copyOf
Map
的实现类较多,在此我们关注 HashMap
、 TreeMap
、 HashTable
、 LinkedHashMap
1.TreeMap
public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, Serializable
- 继承
AbstractMap
,一个红黑树基于NavigableMap
实现 - 非线程安全的
key
不能存null
,但是value
可以存null
key
必须是可比较的 (实现Comparable
接口,传递一个Comparator
比较器)
2.HashTable
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, Serializable
- 该类实现了一个哈希表,它将键映射到值
- 不允许 null 作为键和值
- 默认初始容量( initialCapacity )为 11 ,默认负载因子( loadFactor )为 0.75f
- 同步的(线程安全的)
- 不保证顺序
- 扩容方式是旧容量的2倍 +1
- 为什么hashtable的扩容方式选择为2n+1
- 为了均匀分布,降低冲突率 - 数组 + 链表方式存储实现Hash表存储
- 添加值时
- 如果 hash 一样 equals 为 false 则将当前值添加到链表头
- 如果 hash 一样 equals 为 true 则使用当前值替换原来的值 ( key 相同
public synchronized V put(K key, V value) {
// 值不能为 null
if (value == null) {
throw new NullPointerException();
}
// 确认 key 不在 hashtable 中存在
Entry<?,?> tab[] = table;
// 计算 key 的 hash
int hash = key.hashCode();
// 找 key 应在存放在 数组中的位置
int index = (hash & 0x7FFFFFFF) % tab.length;
// index 位置的元素的 key 和 当前的 key 不一样
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
for(; entry != null ; entry = entry.next) {
// 判断 key 是否相同
if ((entry.hash == hash) && entry.key.equals(key)) {
// 当 key 一样时,替换值
V old = entry.value;
entry.value = value;
return old;
}
}
// 当 key 在 hashtable 中不存在时,添加
addEntry(hash, key, value, index);
return null;
}
private void addEntry(int hash, K key, V value, int index) {
Entry<?,?> tab[] = table;
// 判断是否需要 "扩容"
if (count >= threshold) {
// 对数组进行扩容 (2n + 1),将原有元素重新计算 hash
rehash();
tab = table;
// 将当前的 key 也重新计算 hash
hash = key.hashCode();
index = (hash & 0x7FFFFFFF) % tab.length;
}
// 原来数组中的 entry 对象
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>) tab[index];
// 创建一个 新的 entry 对象, 放到 数组中
tab[index] = new Entry<>(hash, key, value, e);
// 元素个数 +1
count++;
// 修改次数 +1
modCount++;
}
相关文章:

集合框架和泛型二
一、Set接口 1. Set接口概述 java.util.Set 不包含重复元素的集合、不能保证存储的顺序、只允许有一个 null。 public interface Set<E> extends Collection<E>抽象方法,都是继承自 java.util.Collection 接口。 Set 集合的实现类有很多,…...
thinkphp6 入门教程合集(更新中)
thinkphp6 入门(1)--安装、路由规则、多应用模式 thinkphp6 入门(1)--安装、路由规则、多应用模式_软件工程小施同学的博客-CSDN博客 thinkphp6 入门(2)--视图、渲染html页面、赋值 thinkphp6 入门&#…...

openGauss学习笔记-65 openGauss 数据库管理-创建和管理数据库
文章目录 openGauss学习笔记-65 openGauss 数据库管理-创建和管理数据库65.1 前提条件65.2 背景信息65.3 注意事项65.4 操作步骤65.4.1 创建数据库65.4.2 查看数据库65.4.3 修改数据库65.4.4 删除数据库 openGauss学习笔记-65 openGauss 数据库管理-创建和管理数据库 65.1 前提…...

mysql、MHA高可用配置即故障切换
MHA概述 一套优秀的MySQL高可用环境下故障切换和主从复制的软件 MHA的出现就是解决MySQL 单点的问题 MySQL故障过程中,MHA能做到0-30秒内自动完成故障切换 MHA能在故障切换的过程中最大程度上保证数据的一致性以达到真正意义上的高可用 MHA的组成(核…...

使用“vue init mpvue/mpvue-quickstart“初始化mpvue项目时出现的错误及解决办法
当使用"vue init mpvue/mpvue-quickstart"初始化 mpvue 项目时出现 "vue-cli Failed to download repo mpvue/mpvue-quickstart: connect ETIMEDOUT IP地址"原因是 github 的 IP 解析失败,连接超时 解决办法:更改最新的 github 的 …...

Linux-Shell整理集合
Shell变量 参考文章: Shell脚本中变量的使用 shell语法之 , ‘ ‘ , {},, ,‘‘,(),$(())四种语法含义 参考文章: shell语法之 , ‘ ‘ , {},, ,‘‘,(),$(())四种语法含义 grep常用用法 Shell awk命令详解 grep 跟awk连着用: 获取某程序的…...

windows环境下node安装教程(超详细)
安装node.js 1、下载node: 下载地址:下载 | Node.js 中文网 node.js的zip包安装时是直接解压缩后就可以了, node.js的msi包是傻瓜式一路next就可以了 选择一中方式就可以 2、解压后的目录,或者mis安装后的目录如下: 3、安装完后,可以在命令行中输入…...

《TCP/IP网络编程》阅读笔记--并发多进程服务端的使用
目录 1--并发服务器端 2--进程 2-1--进程的相关概念 2-2--fork()创建进程 2-3--僵尸进程 2-4--wait()和waitpid()销毁僵尸进程 3--信号处理 3-1--signal()函数 3-2--sigaction()函数 3--3--利用信号处理技术消灭僵尸进程 4--基于多任务的并发服务器 5--分割 TCP 的…...

【C++】day2学习成果:引用、结构体等等。。。
1.封装一个结构体,结构体中包含一个私有数组,用来存放学生的成绩,包含一个私有变量,用来记录学生个数, 提供一个公有成员函数,void setNum(int num)用于设置学生个数 提供一个公有成员函数:void…...

QT 第五天 TCP通信与数据库
一、数据库增删改查 QT core gui sqlgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your comp…...
Java程序中常用的设计模式有哪些和该种设计模式解决的痛点
设计模式是大量程序员智慧的结晶,是优秀的代码范式,是以前那些大佬程序员的编程经验总结,非常值得学习。 在软件开发中,有许多常用的设计模式,每种模式都解决了特定类型的问题。以下是一些常见的设计模式及其简要介绍&…...

Android12之解析/proc/pid进程参数(一百六十四)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...

正儿八经的雅思口语盘丝洞大法学习总结(长期修改更新)针对23.9月考生
目录 开篇语 李仙童口语大法 具体体系内容 说道科技产品或者说非传统物品 part2回答八大准则 【part2回答八大准则】(一) 【part2回答八大准则】(二) 【part3回答七大准则】(一) Part 1 核心体系 …...

算法竞赛入门【码蹄集新手村600题】(MT1260-1280)C语言
算法竞赛入门【码蹄集新手村600题】(MT1260-1280)C语言 目录MT1260 袋鼠躲猫猫MT1261 留下来的才是幸运数MT1262 约数MT1263 最大的三位约数MT1264 完数MT1265 区间完数MT1266 完数与因子MT1267 亏数MT1268 因数的因数MT1269 区间素数MT1270 素数计算MT1271 三生质数…...

qt连接tcp通信和连接数据库
通过数据库实现学生管理系统 widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//判断数据库对象是否包含了自己使用的数据库 Studemt.dbif(!db.co…...

MySQL Oracle区别
由于SQL Server不常用,所以这里只针对MySQL数据库和Oracle数据库的区别 (1) 对事务的提交 MySQL默认是自动提交,而Oracle默认不自动提交,需要用户手动提交,需要在写commit;指令或者点击commit按钮 (2) 分页查询 MySQL是直接在SQL语…...

Figma实用插件速收藏!精选19个干货插件大公开!
Figma 如今有着大量的插件,在 UI/UX 设计领域,很多工作已经不用真的从零开始做了。用好 Figma 插件,往往能让设计工作事半功倍。不过其中的插件素质差别很大,需要仔细筛选。不过如果你选择了对的插件,合理的设置&#…...

【STM32】FSMC—扩展外部 SRAM 初步使用 1
基于野火指南者《零死角玩转 STM32F103—指南者》的学习 STM32F103系列 FSMC Flexible Static Memory Controller简介 1.详细功能参看《STM32F10x参考手册》,这边是概述 是一个外设,挂载在AHB总线下。 可以用于驱动包括 SRAM、NOR FLASH 以及 NAND FL…...

保姆级教程 --redis启动命令
1、在redis目录 打开命令 windowr 输入cmd 2、输入 redis-server.exe redis.windows.conf 启动redis命令,看是否成功 3、可能会启动失败,报28 Nov 09:30:50.919 # Creating Server TCP listening socket 127.0.0.1:6379: bind: No error 4、报错后&am…...

【C++】构造函数分类 ① ( 构造函数分类简介 | 无参构造函数 | 有参构造函数 | 拷贝构造函数 | 代码示例 - 三种类型构造函数定义与调用 )
文章目录 一、构造函数分类1、构造函数分类简介2、构造函数分类代码分析无参构造函数有参构造函数拷贝构造函数 二、代码示例 - 三种类型构造函数定义与调用 一、构造函数分类 1、构造函数分类简介 C 构造函数可以分为以下几类 : 无参构造函数 : 最简单也是默认的构造函数 , 函…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...

基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...