Java:集合(List、Map、Set)
文章目录
- 1. Collection集合
- 1-1. 迭代器遍历方式
- 1-2. 通过for循环进行遍历
- 1-3. forEach遍历
- 2. List集合
- 2-1. ArrayList底层实现原理
- 2-2. LinkedList底层实现原理
- 3. Set集合
- 3-1. HashSet 底层实现
- 3-2. LinkedHashSet 底层实现
- 3-3. TreeSet
- 4. Collection集合->总结
- 5. Map集合
- 5-1. 通过键找值-进行遍历
- 5-2. 键值对进行遍历
- 5-3. 通过Lambda表达式进行遍历
- 5-4. HashMap 底层实现
- 5-5. LinkedHashMap 底层原理
- 5-6. TreeMap 底层原理
1. Collection集合
本身为一个接口。
包括List、Set集合两种。其中List集合添加的元素有序、可重复、有索引,下面有两个实现类,分别为ArrayList、LinkedList。而Set集合添加的元素是无序的、不重复的、无索引的。它的实现类有HashSet、LinkedHashSet、TreeSet,需要注意的是LinkedHashSet中的元素是有序的,TreeSet中的元素是按照大小默认升序进行排序的。
1-1. 迭代器遍历方式
package jh_study;import java.util.*;public class JHStudy {public static void main(String[] args) {Collection<String> c = new ArrayList<>();for (int i = 0; i < 4; i++) {c.add(String.valueOf(i+1));}Iterator<String> iterator = c.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}}
}
通过集合对象".iterator()"获取其迭代器对象,然后通过“迭代器对象.hasNext()”方法来判断是否已经到末尾;没有到末尾的话,可以通过“迭代器对象.next()”获取对应的元素值,不过获取到元素值之后,其对应的索引(或者指针节点)会指向下一个位置。
1-2. 通过for循环进行遍历
package jh_study;import java.util.*;public class JHStudy {public static void main(String[] args) {Collection<String> c = new ArrayList<>();for (int i = 0; i < 4; i++) {c.add(String.valueOf(i+1));}for (String s : c) {System.out.println(s);}}
}
这种方式遍历集合,本质上就是迭代器遍历集合的简化写法。
1-3. forEach遍历
package jh_study;import java.util.*;
import java.util.function.Consumer;public class JHStudy {public static void main(String[] args) {Collection<String> c = new ArrayList<>();for (int i = 0; i < 4; i++) {c.add(String.valueOf(i+1));}// 匿名内部类写法c.forEach(new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}});// 简化c.forEach((e)->{System.out.println(e);});// 再简化c.forEach((e)-> System.out.println(e));// 再简化c.forEach(System.out::println);}
}
Collection是一个接口,因此实现了该接口对应的类都具备其下的方法。
2. List集合
遍历元素方式除了上述三种之外,还可以通过下标索引进行遍历,当然需要使用到for循环
package jh_study;import java.util.*;public class JHStudy {public static void main(String[] args) {List<Integer> l = new ArrayList<>();l.add(12);l.add(0);for (int i = 0; i < l.size(); i++) {System.out.println(l.get(i));}}
}
2-1. ArrayList底层实现原理
底层实现是基于数组实现的,查看源代码可以发现。
根据索引查询速度快(查询数据通过地址值和索引进行定位,查询任意数据耗时相同),删除效率低(可能需要把后面很多的数据进行前移),添加效率低(可能需要把后面很多的数据后移,再添加元素;或者也可能需要进行数组扩容。)
ArrayList底层实现原理:
1.利用无参构造器创建的集合,会在底层创建一个默认长度为0的数组;
2.添加第一个元素时,底层会创建一个新的长度为10的数组;
3.存满时,会扩容1.5倍;
如果一次添加多个元素,1.5倍还放不下,则新创建的数组的长度以实际为准;
2-2. LinkedList底层实现原理
底层实现是双向链表。
LinkedList的应用场景:实现栈(后进先出)、队列(先进先出)。
3. Set集合
正如上述所说,常见的set集合类型有HashSet、LinkedHashSet、TreeSet。其中,HashSet特点为无序、不重复、无索引;LinkedHashSet特点为有序、不重复、无索引;TreeSet特点为升序、不重复、无索引。
package jh_study;import java.util.*;public class JHStudy {public static void main(String[] args) {Set<Integer> set = new HashSet<>();Set<Integer> set1 = new LinkedHashSet<>();Set<Integer> set2 = new TreeSet<>();System.out.println("HashSet集合");set.add(333);set.add(2222);set.add(1111);set.add(2333);System.out.println(set);System.out.println("LinkedHashSet集合");set1.add(333);set1.add(2222);set1.add(1111);set1.add(2333);System.out.println(set1);System.out.println("TreeSet集合");set2.add(333);set2.add(2222);set2.add(1111);set2.add(2333);System.out.println(set2);}
}
3-1. HashSet 底层实现
关于hash值,就是一个int类型的数值,Java中每一个对象都有一个hash值;Java中所有的对象,都可以通过调用Object类提供的hashCode方法,返回该对象自己的hash值。
hash值的特点:同一个对象多次调用hashCode方法返回的hash值是相同的;不同对象,它们的hash值一般不相同,但是也有可能相同(hash碰撞)。
HashSet底层原理:是基于hash表实现的,hash表是一种增删改查数据性能都较好的数据结构。在jdk8之前,hash表的实现是基于数组+链表实现的;jdk8之后,hash表的实现是基于数组+链表+红黑树实现的。
jdk8之前的哈希表底层实现为:创建一个默认长度为16的数组,默认加载因子为0.75(也就是当长度为12时,会进行扩容操作,原数组中的元素会添加到新数组当中去);使用元素的哈希值对数组长度求余计算出应存入的位置;判断当前位置是否为null,如果为null直接存入,如果不为null,表示该位置有元素,则调用equals方法进行比较,相等,则不存,不相等,则存入数组,也就是在数组对应的位置上创建链表,元素存入到链表中进行存储。在jdk8之后,当链表长度超过8,并且数组长度大于或等于64时,自动将链表转换为红黑树。
jdk8之前的Hash表结构。
jdk8之后的Hash表结构。
如果在HashSet中有两个内容相同但是它们hash值不同,此时如果我们想去重的话,需要重写其hashCode和equals方法。
package jh_study;import java.util.HashSet;
import java.util.Objects;
import java.util.Set;class User{private String name;private Integer age;public User(String name, Integer age) {this.name = name;this.age = age;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;User user = (User) o;return Objects.equals(name, user.name) && Objects.equals(age, user.age);}@Overridepublic int hashCode() {return Objects.hash(name, age);}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class JHStudy2 {public static void main(String[] args) {Set<User> users = new HashSet<>();users.add(new User("张三",20));users.add(new User("张三",20));System.out.println(users);}
}
3-2. LinkedHashSet 底层实现
LinkedHashSet为HashSet的子类,底层实现依旧是基于哈希表(数组、链表、红黑树)实现的。但是,它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置。
3-3. TreeSet
底层实现基于红黑树实现的升序排序(默认情况下),特点是不重复、无索引、可排序(默认升序排序)。如果在TreeSet中存储的数类型为自定义类型(比如Student),此时如果打印输出结果会报错,因此TreeSet类型并不知道通过Student那个属性进行计较,此时可以在Student类下,让其实现Comparable接口,并重写方法compareTo;当然,也可以直接在定义TreeSet类型的变量时,给上参数new Comparator比较器对象,让其实现方法compare。
package jh_study;import java.util.*;public class JHStudy3 {public static void main(String[] args) {Set<Integer> set = new TreeSet<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2-o1;}});// 简化写法/*Set<Integer> set = new TreeSet<>((a,b)->{return b - a;});*/set.add(3);set.add(1);set.add(2);System.out.println(set);}
}
如果上述两种都设置了,类对象实现了Comparable接口,定义TreeSet变量时指定了比较器,那么采用就近原则上那个(也就是比较器)来进行排序的。
4. Collection集合->总结
- 如果希望记住元素的添加顺序,需要存储重复的元素,又要频繁的根据索引查询数据,可以采用ArrayList集合类型(底层实现基于数组,特点是有序、可重复、有索引);
- 如果希望记住元素的添加顺序,且增删首尾数据的情况较多,可以采用LinkedList集合类型(底层实现基于双链表,特点是有序、可重复、有索引);
- 如果不在意元素顺序,也没有重复元素需要存储,只希望增删查改都快,可以采用HashSet集合类型;(底层实现基于哈希表,特点是无序、不重复、无索引)
- 如果希望记住元素的添加顺序,也没有重复元素需要存储,且希望增删改查都快,可以采用LinkedHashSet集合类型(底层实现基于哈希表和双链表,特点为有序、不重复、无索引);
- 如果要对元素进行排序,也没有重复元素需要存储,且希望增删改查都快,可以采用TreeSet集合类型(底层实现基于红黑树,特点为升序、不重复、无索引);
5. Map集合
键值对集合,键不能重复,值可以重复。
常见的比如HashMap(无序、不重复、无索引)、TreeMap(有序、不重复、无索引)、LinkedHashMap(按照大小默认升序排序,不重复,无索引)。
package jh_study;import java.util.*;public class JHStudy4 {public static void main(String[] args) {Map<String, String> map = new HashMap<>();map.put(null,null);map.put("张三","男");map.put("李四","女");map.put("嘻嘻1","MyDream");System.out.println(map);// {null=null, 李四=女, 张三=男, 嘻嘻1=MyDream}System.out.println(map.get("张三"));//男 ,获取键对应的值System.out.println(map.get("赵六"));// null ,不存在的键System.out.println(map.containsKey("李四"));// 判断是否存在某个键 true// map.clear();// 清空map中的数据Set<String> set = map.keySet();System.out.println(set);// 获取所有的键 [null, 李四, 张三, 嘻嘻1]System.out.println(map.isEmpty());// 判断map是否为空 falseSystem.out.println(map.values());// 获取map中所有的值 [null, 女, 男, MyDream]System.out.println(map.size());// 获取map的长度 4System.out.println(map.remove("张三"));// 删除某个键,并返回这个键对应的值 男}
}
5-1. 通过键找值-进行遍历
通过Map对象的 keySet() 方法获取对应的键集合,然后通过遍历键集合来获取对应的值。
package jh_study;import java.util.*;public class JHStudy4 {public static void main(String[] args) {Map<String, String> map = new HashMap<>();map.put(null,null);map.put("张三","男");map.put("李四","女");map.put("嘻嘻1","MyDream");map.put("赵六","man");Set<String> keys = map.keySet();for (String key : keys) {System.out.println(key+"->"+map.get(key));}}
}
5-2. 键值对进行遍历
通过Map对象的 entrySet() 方法获取键值对集合,然后对这个集合进行遍历即可。
package jh_study;import java.util.*;public class JHStudy4 {public static void main(String[] args) {Map<String, String> map = new HashMap<>();map.put(null,null);map.put("张三","男");map.put("李四","女");map.put("嘻嘻1","MyDream");map.put("赵六","man");Set<Map.Entry<String, String>> set = map.entrySet();for (Map.Entry<String, String> entry : set) {System.out.println(entry.getKey()+"=>"+entry.getValue());}}
}
5-3. 通过Lambda表达式进行遍历
package jh_study;import java.util.*;
import java.util.function.BiConsumer;public class JHStudy4 {public static void main(String[] args) {Map<String, String> map = new HashMap<>();map.put(null,null);map.put("张三","男");map.put("李四","女");map.put("嘻嘻1","MyDream");map.put("赵六","man");map.forEach(new BiConsumer<String, String>() {@Overridepublic void accept(String s, String s2) {System.out.println(s+" "+s2);}});// 简化map.forEach((k,v)-> System.out.println(k+" "+v));}
}
5-4. HashMap 底层实现
HashMap和HashSet的底层实现原理都是一样的,都是基于哈希表实现的。在JDK8之前,其哈希表基于数组+链表;JDK8之后,其哈希表基于数组+链表+红黑树实现。
5-5. LinkedHashMap 底层原理
LinkedHashMap 和 LinkedHashSet的底层原理是一样的。
5-6. TreeMap 底层原理
TreeMap和TreeSet的底层实现原理都是一样的。
如果要对数据进行排序,也有两种方式,和TreeSet一样,参考代码如下:
方法1:让需要排序的对象数据实现Comparable即可,并重写方法compareTo。
package jh_study;import java.util.*;public class JHStudy4 {public static void main(String[] args) {Map<User4, Integer> map = new TreeMap<>();map.put(new User4("张三",23),0);map.put(new User4("李四",12),1);map.put(new User4("王五",10),2);map.put(new User4("赵六",25),3);System.out.println(map);}
}class User4 implements Comparable<User4>{String name;Integer age;public User4(String name, Integer age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "User4{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int compareTo(User4 o) {return o.age - this.age;}
}
方法2:通过比较器,参考代码如下:
package jh_study;import java.util.*;public class JHStudy4 {public static void main(String[] args) {Map<User4, Integer> map = new TreeMap<>(new Comparator<User4>() {@Overridepublic int compare(User4 o1, User4 o2) {return o1.age-o2.age;}});map.put(new User4("张三",23),0);map.put(new User4("李四",12),1);map.put(new User4("王五",10),2);map.put(new User4("赵六",25),3);System.out.println(map);}
}
相关文章:

Java:集合(List、Map、Set)
文章目录 1. Collection集合1-1. 迭代器遍历方式1-2. 通过for循环进行遍历1-3. forEach遍历 2. List集合2-1. ArrayList底层实现原理2-2. LinkedList底层实现原理 3. Set集合3-1. HashSet 底层实现3-2. LinkedHashSet 底层实现3-3. TreeSet 4. Collection集合->总结5. Map集…...

使用秘钥登录服务器
在我们测试或生产环境中,为了服务器安全性,有时可能需要以 SSH 密钥的方式登录服务器,接下来,将演示如何通过 SSH 私钥的方式来远程服务器。 一、远程服务器生成密钥对 1、首先在目标远程服务器下生成 SSH 密钥对 ssh-keygen然…...

BFS算法题
目录 1.BFS 2.树里的宽搜 题目一——429. N 叉树的层序遍历 - 力扣(LeetCode) 题目二——103. 二叉树的锯齿形层序遍历 - 力扣(LeetCode) 题目三——662. 二叉树最大宽度 - 力扣(LeetCode) 题目四——…...

网络应用技术 实验八:防火墙实现访问控制(华为ensp)
目录 一、实验简介 二、实验目的 三、实验需求 四、实验拓扑 五、实验步骤 1、设计全网 IP 地址 2、设计防火墙安全策略 3、在 eNSP 中部署园区网 4、配置用户主机地址 5、配置网络设备 配置交换机SW-1~SW-5 配置路由交换机RS-1~RS-5 配置路由器R-1~R-3 6、配置仿…...

嵌入式现状、机遇、挑战与展望
在当今数字化浪潮中,嵌入式系统宛如一颗璀璨的明珠,熠熠生辉,深刻地渗透到了我们生活的方方面面,成为推动现代科技进步不可或缺的关键力量。从智能家居的便捷控制,到工业生产的精准运作,再到汽车的智能驾驶…...

天通卫星卡通知短信模板
文章目录 引言I 阿里云新增短信模板短信模板通知短信变量规范计费规则: 短信长度不超过70个字,按照1条短信计费;II 表设计III 实现方案引言 背景:天通卡适用于应急救灾、登山探险、海上通信、野外作业等需要稳定可靠通信的场景。 需求:天通卡充值成功通知 平台基于阿里云给…...

Unity WebGL 编译和打包说明(官方文档翻译校正)
目录 Unity WebGL 编译和打包说明WebGL 简介WebGL 浏览器兼容性 (WebGL Browser Compatibility)平台支持 (Platform Support)多线程支持限制多线程支持的因素安装 Unity Hub 并添加所需模块WebGL 开发WebGL Player 设置Resolution and PresentationResolutionWebGL TemplateSpl…...

题解 - 取数排列
题目描述 取1到N共N个连续的数字(1≤N≤9),组成每位数不重复的所有可能的N位数,按从小到大的顺序进行编号。当输入一个编号M时,就能打印出与该编号对应的那个N位数。例如,当N=3时,可…...
JAVA实战:借助阿里云实现短信发送功能
亲爱的小伙伴们😘,在求知的漫漫旅途中,若你对深度学习的奥秘、JAVA 、PYTHON与SAP 的奇妙世界,亦或是读研论文的撰写攻略有所探寻🧐,那不妨给我一个小小的关注吧🥰。我会精心筹备,在…...
高阶函数:JavaScript 编程中的魔法棒
在JavaScript的世界里,高阶函数是一种强大的工具,它允许我们将函数作为参数传递或将函数作为返回值。这种特性使得JavaScript代码更加灵活和强大。本文将深入探讨高阶函数的定义、用法以及在实际项目中的最佳实践,帮助大家更好地理解和应用这…...
Android 12.0 Launcher3从首页开始安装app功能实现
1.前言 在12.0的系统rom定制化开发中,在进行Launcher3的某些功能开发实现过程中,在某些项目中,安装的app比较多,要求在launcher3的首页开始安装 app应用,接下来就需要分析下app安装图标排序的流程,然后在实现相关的功能 2. Launcher3从首页开始安装app功能实现的核心…...

软考高级架构 - 10.5 软件架构演化评估方法
10.4 软件架构演化原则总结 本节提出了18条架构演化的核心原则,并为每条原则设计了简单而有效的度量方法,用于从系统整体层面提供实用信息,帮助评估和指导架构演化。 演化成本控制:成本小于重新开发成本,经济高效。进…...
半导体制造全流程
半导体制造是一个极其复杂且精密的过程,主要涉及将硅片加工成功能强大的芯片。以下是半导体制造的全流程概述: 1. 硅材料制备 硅提纯: 使用冶金级硅,进一步提纯为高纯度硅(电子级硅),纯度可达 …...
国科大网络协议安全期末
完整资料仓库地址:https://gitee.com/etsuyou/UCAS-Network-Protocol-Security 部分题目: 六 论述题10*220 试讨论IPv6解决了IPv4的哪些“痛点”,以及IPv6存在的安全问题试比较IPsec与SSL的安全性 五 简答题5*315 简述MAC欺骗和ARP欺骗的…...
ES动态索引——日志es索引数据按月份存储
一、定义ES索引 NoArgsConstructor AllArgsConstructor Data Accessors(chain true) Document(indexName "charge_pile_log" Constants.ES_TIME_DYNAMIC_INDEX) //(索引名称动态,前面固定,后面月份) public class ChargePileLogESDomain {…...

NLP论文速读(ICML 2024)|面相对齐大语言模型的迁移和合并奖励模型方法
论文速读|Transforming and Combining Rewards for Aligning Large Language Models 论文信息: 简介: 本文探讨了如何使大型语言模型(LLMs)与人类偏好对齐。传统的对齐方法是先从偏好数据中学习一个奖励模型,然后使用这…...
蓝桥杯我来了
最近蓝桥杯报名快要截止了,我们学校开始收费了,我们学校没有校赛,一旦报名缴费就是省赛,虽然一早就在官网上报名了,但是一直在纠结,和家人沟通,和朋友交流,其实只是想寻求外界的支持…...

Vue3+TypeScript+AntVX6实现Web组态(从技术层面与实现层面进行分析)内含实际案例教学
摘要 用Vue3+TypeScript+AntVX6实现Web组态(从技术层面与实现层面进行分析),包含画布创建、节点设计、拖拽实现(实际案例)、节点连线、交互功能,后续文章持续更新。 注:本文章可以根据目录进行导航 文档支持 AntVX6使用文档 https://x6.antv.antgroup.com/tutorial…...

【LeetCode】每日一题 2024_12_13 K 次乘运算后的最终数组 I(暴力)
前言 每天和你一起刷 LeetCode 每日一题~ 小聊两句 1、今天是 12.13 南京大屠杀国家公祭日。铭记历史,勿忘国耻。 2、今天早上去看了 TGA 年度游戏颁奖,小机器人拿下了年度最佳游戏,所有人都震惊了,大伙纷纷问到,谁…...
Plant simulation、Flexsim、Automod、Emulate3D、VisuaComponent仿真软件对比
软件名称物流系统仿真工业布局仿真动画效果数据分析优化虚拟现实/混合现实二次开发虚拟电控和PLC调试 软件行业内特殊功能Emulate3D1.物流设备模块完备,功能灵活设置,涵盖各种设备形态和运作方式 2.唯一将摩擦力、重力、阻力等物理属性融入到物流运动中&…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...