Java集合框架扫盲

文章目录

  • 一、故事背景
  • 二、知识点主要构成
    • 1、List
      • 1.1、ArrayList
        • 1.1.1、添加元素
        • 1.1.2、删除元素
        • 1.1.3、修改元素
        • 1.1.4、遍历元素
      • 1.2、LinkedList
        • 1.2.1、添加元素
        • 1.2.2、删除元素
        • 1.2.3、修改元素
        • 1.2.4、遍历元素
      • 1.3、Vector
    • 2、Set
      • 2.1、HashSet
      • 2.2、LinkedHashSet
      • 2.3、TreeSet
    • 3、Queue
      • 3.1、ArrayDeque
    • 4、Map
      • 4.1、HashMap
      • 4.2、LinkedHashMap
      • 4.3、TreeMap
  • 三、总结提升

一、故事背景

最近在整理Java整个集合框架相关的内容,有很多东西在日常项目开发中没有用到过,总结一篇博客给大家扫扫盲,此篇博客包含Java中所有集合容器的相关使用,如有遗漏还请指出;

二、知识点主要构成

在介绍集合框架之前,先来看一张图,俗话说不谋全局者不足以谋一域么,先整理了解一下集合框架都有哪些东西;
在这里插入图片描述
Java 集合框架可以分为两条大的支线:

  • Collection,主要由 List、Set、Queue 组成,List 代表有序、可重复的集合,典型代表就是封装了动态数组的 ArrayList 和封装了链表的 LinkedList;Set 代表无序、不可重复的集合,典型代表就是 HashSet 和 TreeSet;Queue 代表队列,典型代表就是双端队列 ArrayDeque,以及优先级队列 PriorityQueue。
  • Map,代表键值对的集合,典型代表就是 HashMap。

1、List

1.1、ArrayList

ArrayList 是由数组实现的,支持随机存取,也就是可以通过下标直接存取元素;
从尾部插入和删除元素会比较快捷,从中间插入和删除元素会比较低效,因为涉及到数组元素的复制和移动;
如果内部数组的容量不足时会自动扩容,因此当元素非常庞大的时候,效率会比较低。

1.1.1、添加元素

    public static void main(String[] args) {// 创建一个集合ArrayList<String> list = new ArrayList<>();// 添加元素list.add("www");list.add("mmm");list.add("jjj");}

1.1.2、删除元素

// 删除元素public static void main(String[] args) {// 创建一个集合ArrayList<String> list = new ArrayList<>();// 添加元素list.add("www");list.add("mmm");list.add("jjj");// 删除元素list.remove(1);}

1.1.3、修改元素

// 删除元素public static void main(String[] args) {// 创建一个集合ArrayList<String> list = new ArrayList<>();// 添加元素list.add("www");list.add("mmm");list.add("jjj");// 修改元素list.set(1, "mjw");}

1.1.4、遍历元素

		// 遍历集合 for 循环for (int i = 0; i < list.size(); i++) {String s = list.get(i);System.out.println(s);}// 遍历集合 for eachfor (String s : list) {System.out.println(s);}

1.2、LinkedList

LinkedList 是由双向链表实现的,不支持随机存取,只能从一端开始遍历,直到找到需要的元素后返回;
任意位置插入和删除元素都很方便,因为只需要改变前一个节点和后一个节点的引用即可,不像 ArrayList 那样需要复制和移动数组元素;
因为每个元素都存储了前一个和后一个节点的引用,所以相对来说,占用的内存空间会比 ArrayList 多一些。

1.2.1、添加元素

public static void main(String[] args) {// 创建一个集合LinkedList<String> list = new LinkedList<>();// 添加元素list.add("王");list.add("沉");list.add("qubg");}

1.2.2、删除元素

public static void main(String[] args) {// 创建一个集合LinkedList<String> list = new LinkedList<>();// 添加元素list.add("你");list.add("好");list.add("呀");// 删除元素list.remove(1);}

1.2.3、修改元素

public static void main(String[] args) {// 创建一个集合LinkedList<String> list = new LinkedList<>();// 添加元素list.add("你");list.add("好");list.add("呀");// 修改元素list.set(1, "二狗");}

1.2.4、遍历元素

public static void main(String[] args) {// 创建一个集合LinkedList<String> list = new LinkedList<>();// 添加元素list.add("你");list.add("好");list.add("呀");// 遍历集合 for 循环for (int i = 0; i < list.size(); i++) {String s = list.get(i);System.out.println(s);}// 遍历集合 for eachfor (String s : list) {System.out.println(s);}}

LinkedList也实现了 Deque 接口,可以作为队列来使用。等于说,LinkedList 同时实现了 Stack、Queue、PriorityQueue 的所有功能。
在这里插入图片描述
通过源码可以看到LinkedList同时实现了List和Deque接口,说明LinkedList是Java 集合框架中的双向队列。

1.3、Vector

List 的实现类还有一个 Vector,是一个元老级的类,比 ArrayList 出现得更早。ArrayList 和 Vector 非常相似,只不过 Vector 是线程安全的,像 get、set、add 这些方法都加了 synchronized 关键字,就导致执行执行效率会比较低,所以现在已经很少用了。
在这里插入图片描述
同时也可以看到JDK官方注释说明:如果不需要线程安全,建议使用ArrayList代替Vector。
在这里插入图片描述

2、Set

Set 的特点是存取无序,不可以存放重复的元素,不可以用下标对元素进行操作,和 List 有很多不同。

2.1、HashSet

废话不多话,直接看相关操作;

    public static void main(String[] args) {// 创建一个新的HashSetHashSet<String> set = new HashSet<>();// 添加元素set.add("www");set.add("王");set.add("ddd");// 输出HashSet的元素个数System.out.println("HashSet size: " + set.size()); // output: 3// 判断元素是否存在于HashSet中boolean containsWanger = set.contains("王");System.out.println("Does set contain '王'? " + containsWanger); // output: true// 删除元素boolean removeWanger = set.remove("王");System.out.println("Removed '王'? " + removeWanger); // output: true// 修改元素,需要先删除后添加boolean removeChenmo = set.remove("ddd");boolean addBuChenmo = set.add("vvvvvvv");System.out.println("Modified set? " + (removeChenmo && addBuChenmo)); // output: true// 输出修改后的HashSetSystem.out.println("HashSet after modification: " + set);}

2.2、LinkedHashSet

LinkedHashSet 虽然继承自 HashSet,其实是由 LinkedHashMap 实现的。
看一下LinkedHashSet的构造方法:
在这里插入图片描述
其中在LinkedHashSet的无参构造方法中执行super(16,.75f,true),意思是执行父类的构造函数,继续执行可以看到:
在这里插入图片描述
实际new出来的是一个LinkedHashMap。
接下来看一段基于LinkedHashSet的相关操作:

public static void main(String[] args) {LinkedHashSet<String> set = new LinkedHashSet<>();// 添加元素set.add("大家");set.add("晚上");set.add("好呀");// 删除元素set.remove("大家");// 修改元素set.remove("晚上");set.add("中午");// 查找元素boolean hasChenQingYang = set.contains("好呀");System.out.println("set包含好呀?" + hasChenQingYang);}

LinkedHashSet是一种基于哈希表实现的Set接口,它继承自HashSet,并且使用链表维护了元素的插入顺序。因此,它既具有HashSet的快速查找、插入和删除操作的优点,又可以维护元素的插入顺序。

2.3、TreeSet

同样,TreeSet是基于TreeMap实现的,可以看TreeSet的构造方法:
在这里插入图片描述
TreeSet 是一种基于红黑树实现的有序集合,它实现了 SortedSet 接口,可以自动对集合中的元素进行排序。按照键的自然顺序或指定的比较器顺序进行排序。

    public static void main(String[] args) {// 创建一个 TreeSet 对象TreeSet<String> set = new TreeSet<>();// 添加元素set.add("大家");set.add("晚上");set.add("好呀");System.out.println(set); // 输出 [大家,晚上,好呀]// 删除元素set.remove("大家");System.out.println(set); // 输出 [晚上,好呀]// 修改元素:TreeSet 中的元素不支持直接修改,需要先删除再添加set.remove("晚上");set.add("中午");System.out.println(set); // 输出 [中午,好呀]// 查找元素System.out.println(set.contains("晚上")); // 输出 trueSystem.out.println(set.contains("喵喵喵")); // 输出 false}

3、Queue

队列,学习过基本数据结构的大家应该都知道,队列是遵循先进先出(FIFO)原则的。来看一个简易队列:
在这里插入图片描述

3.1、ArrayDeque

ArrayDeque 是一个基于数组实现的双端队列,为了满足可以同时在数组两端插入或删除元素的需求,数组必须是循环的,也就是说数组的任何一点都可以被看作是起点或者终点。
在这里插入图片描述

public static void main(String[] args) {// 创建一个ArrayDequeArrayDeque<String> deque = new ArrayDeque<>();//添加元素deque.add("兄弟们");deque.add("姐妹们");deque.add("早上好");deque.addFirst("1");deque.addFirst("3");deque.addLast("2");System.out.println(deque.getLast());System.out.println(deque.getFirst());// 删除元素deque.remove("兄弟们");// 修改元素deque.remove("姐妹们");deque.add("大家");// 查找元素boolean hasChenQingYang = deque.contains("大家");System.out.println("deque包含大家吗?" + hasChenQingYang);}

LinkedList 和 ArrayDeque 都是 Java 集合框架中的双向队列(deque),它们都支持在队列的两端进行元素的插入和删除操作。不过,LinkedList 和 ArrayDeque 在实现上有一些不同:

  • 底层实现方式不同:LinkedList 是基于链表实现的,而 ArrayDeque 是基于数组实现的。
  • 随机访问的效率不同:由于底层实现方式的不同,LinkedList 对于随机访问的效率较低,时间复杂度为 O(n),而 ArrayDeque 可以通过下标随机访问元素,时间复杂度为 O(1)。
  • 迭代器的效率不同:LinkedList 对于迭代器的效率比较低,因为需要通过链表进行遍历,时间复杂度为 O(n),而 ArrayDeque 的迭代器效率比较高,因为可以直接访问数组中的元素,时间复杂度为 O(1)。
  • 内存占用不同:由于 LinkedList 是基于链表实现的,它在存储元素时需要额外的空间来存储链表节点,因此内存占用相对较高,而 ArrayDeque 是基于数组实现的,内存占用相对较低。

因此,在选择使用 LinkedList 还是 ArrayDeque 时,需要根据具体的业务场景和需求来选择。如果需要在双向队列的两端进行频繁的插入和删除操作,并且需要随机访问元素,可以考虑使用 ArrayDeque;如果需要在队列中间进行频繁的插入和删除操作,可以考虑使用 LinkedList。

4、Map

Map 保存的是键值对,键要求保持唯一性,值可以重复。

4.1、HashMap

HashMap 实现了 Map 接口,可以根据键快速地查找对应的值——通过哈希函数将键映射到哈希表中的一个索引位置,从而实现快速访问。
HashMap 有一个初始容量和一个负载因子。初始容量是指哈希表的初始大小,负载因子是指哈希表在扩容之前可以存储的键值对数量与哈希表大小的比率。默认的初始容量是 16,负载因子是 0.75。

    public static void main(String[] args) {// 创建一个 HashMap 对象HashMap<String, String> hashMap = new HashMap<>();// 添加键值对hashMap.put("wmj", "王梦杰");hashMap.put("cyx", "陈奕迅");hashMap.put("zj", "张杰");// 获取指定键的值String value1 = hashMap.get("zj");System.out.println("zj对应的值为:" + value1);// 修改键对应的值hashMap.put("wmj", "wangmengjie");String value2 = hashMap.get("沉默");System.out.println("修改后wmj对应的值为:" + value2);// 删除指定键的键值对hashMap.remove("zj");// 遍历 HashMapfor (String key : hashMap.keySet()) {String value = hashMap.get(key);System.out.println(key + " 对应的值为:" + value);}}

4.2、LinkedHashMap

LinkedHashMap 是 HashMap 的子类,它使用链表来记录插入/访问元素的顺序。
LinkedHashMap 可以看作是 HashMap + LinkedList 的合体,它使用了哈希表来存储数据,又用了双向链表来维持顺序。
来看一下LinkedHashMap和HashMap对比程序:
首先是LinkedHashMap:创建了一个LinkedHashMap,插入几个键值对,然后遍历打印结果;

public static void main(String[] args) {// 创建一个 LinkedHashMap,插入键值对LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();linkedHashMap.put("wmj", "王梦杰");linkedHashMap.put("cyx", "陈奕迅");linkedHashMap.put("zj", "张杰");// 遍历 LinkedHashMapfor (String key : linkedHashMap.keySet()) {String value = linkedHashMap.get(key);System.out.println(key + " 对应的值为:" + value);}}

在这里插入图片描述
从打印结果我们得知,输出打印的次序和插入的顺序是一致的,说明LinkedHashMap是一个有序的键值对集合;
接下来可以看一下HashMap的打印结果产生一下对比:

public static void main(String[] args) {// 创建一个 HashMap 对象HashMap<String, String> hashMap = new HashMap<>();// 添加键值对hashMap.put("wmj", "王梦杰");hashMap.put("cyx", "陈奕迅");hashMap.put("zj", "张杰");// 遍历 HashMapfor (String key : hashMap.keySet()) {String value = hashMap.get(key);System.out.println(key + " 对应的值为:" + value);}}

来看结果,得知HashMap没有维持键值对的插入顺序。
在这里插入图片描述

4.3、TreeMap

TreeMap实现了 SortedMap 接口,可以自动将键按照自然顺序或指定的比较器顺序排序,并保证其元素的顺序。内部使用红黑树来实现键的排序和查找。

public static void main(String[] args) {// 创建一个 TreeMap 对象Map<String, String> treeMap = new TreeMap<>();// 向 TreeMap 中添加键值对treeMap.put("wmj", "王梦杰");treeMap.put("cyx", "陈奕迅");treeMap.put("zj", "张杰");// 查找键值对String name = "wmj";if (treeMap.containsKey(name)) {System.out.println("找到了 " + name + ": " + treeMap.get(name));} else {System.out.println("没有找到 " + name);}// 修改键值对name = "wmj";if (treeMap.containsKey(name)) {System.out.println("修改前的" + name + ": " + treeMap.get(name));treeMap.put(name, "wangmengjie");System.out.println("修改后的 " + name + ": " + treeMap.get(name));} else {System.out.println("没有找到 " + name);}// 删除键值对name = "zj";if (treeMap.containsKey(name)) {System.out.println("删除前的 " + name + ": " + treeMap.get(name));treeMap.remove(name);System.out.println("删除后的 " + name + ": " + treeMap.get(name));} else {System.out.println("没有找到 " + name);}// 遍历 TreeMapfor (Map.Entry<String, String> entry : treeMap.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());}}

三、总结提升

此篇文章总结了常用集合的一些基本操作,当然,我们不能只会使用它,更加去研究它是如何实现的,这样才能去学习它,成为它,超越它。
如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏哦。

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

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

相关文章

启动audit服务报错

启动centos audit服务报错 错误信息 $service auditd restart Stopping logging: [FAILED] Redirecting start to /bin/systemctl start auditd.service Job for auditd.service failed because the control process exited with error code. See “systemctl status auditd.s…

java-CyclicBarrier、CountDownLatch、Semaphore 的用法以及 volatile 关键字的作用

CyclicBarrier、CountDownLatch、Semaphore 的用法 1. CountDownLatch&#xff08;线程计数器 &#xff09; CountDownLatch 类位于 java.util.concurrent 包下&#xff0c;利用它可以实现类似计数器的功能。比如有一个任务 A&#xff0c;它要等待其他 4 个任务执行完毕之后才…

Selenium环境+元素定位大法

selenium 与 webdriver Selenium 是一个用于 Web 测试的工具&#xff0c;测试运行在浏览器中&#xff0c;就像真正的用户在手工操作一样。支持所有主流浏览器 WebDriver 就是对浏览器提供的原生API进行封装&#xff0c;使其成为一套更加面向对象的Selenium WebDriver API。 使…

08-信息收集-架构、搭建、WAF等

信息收集-架构、搭建、WAF等 信息收集-架构、搭建、WAF等一、前言说明二、CMS识别技术三、源码获取技术四、架构信息获取技术五、站点搭建分析1、搭建习惯-目录型站点2、搭建习惯-端口类站点3、搭建习惯-子域名站点4、搭建习惯-类似域名站点5、搭建习惯-旁注&#xff0c;c段站点…

Python“牵手”易贝(Ebay)商品列表数据,关键词搜索ebayAPI接口数据,ebayAPI接口申请指南

Ebay平台API接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范&#xff0c; EbayAPI接口是指通过编程的方式&#xff0c;让开发者能够通过HTTP协议直接访问Ebay平台的数据&#xff0c;包括商品信息、店铺信息、物流信息等&#xff0c;从而实现Ebay平…

MediaPlayer音频与视频的播放介绍

作者&#xff1a;向阳逐梦 Android多媒体中的——MediaPlayer&#xff0c;我们可以通过这个API来播放音频和视频该类是Androd多媒体框架中的一个重要组件&#xff0c;通过该类&#xff0c;我们可以以最小的步骤来获取&#xff0c;解码和播放音视频。 它支持三种不同的媒体来源…

Spring Boot进阶(58):集成PostgreSQL数据库及实战使用 | 万字长文,超级详细

1. 前言&#x1f525; PostgreSQL是一种广泛使用的开源关系型数据库&#xff0c;具有可靠性高、性能优异、拥有丰富的数据类型和扩展等优点&#xff0c;越来越多的企业和开发者开始使用它来存储和管理数据。而Spring Boot是一种快速开发的框架&#xff0c;可以简化开发过程并提…

【业务功能篇77】微服务-OSS对象存储-上传下载图片

3. 图片管理 文件存储的几种方式 单体架构可以直接把图片存储在服务器中 但是在分布式环境下面直接存储在WEB服务器中的方式就不可取了&#xff0c;这时我们需要搭建独立的文件存储服务器。 3.1 开通阿里云服务 针对本系统中的相关的文件&#xff0c;图片&#xff0c;文本等…

Django基础3——视图函数

文章目录 一、基本了解1.1 Django内置函数1.2 http请求流程 二、HttpRequest对象&#xff08;接受客户端请求&#xff09;2.1 常用属性2.2 常用方法2.3 服务端接收URL参数2.4 QueryDict对象2.5 案例2.5.1 表单GET提交2.5.2 表单POST提交2.5.3 上传文件 三、HttpResponse对象&am…

时序预测 | MATLAB实现PSO-KELM粒子群算法优化核极限学习机时间序列预测(含KELM、ELM等对比)

时序预测 | MATLAB实现PSO-KELM粒子群算法优化核极限学习机时间序列预测&#xff08;含KELM、ELM等对比&#xff09; 目录 时序预测 | MATLAB实现PSO-KELM粒子群算法优化核极限学习机时间序列预测&#xff08;含KELM、ELM等对比&#xff09;预测效果基本介绍模型介绍程序设计参…

【AWS】安装配置适用于 Eclipse 的 AWS 工具包

目录 0.环境 1.步骤 1&#xff09;安装Eclipse 2&#xff09;安装AWS工具包 ① 在这个路径下点开安装软件的界面 ② 点击【Add】打开添加窗口 ③ 输入aws的工具包地址 ④ 勾选需要的工具&#xff0c;点击【Next】 ⑤ 将要安装的工具&#xff0c;点击【Next】 ⑥ 选择接受…

当 SQL Server(mssql-jdbc) 遇上 BigDecimal

需求背景 系统对接了外部系统&#xff0c;调用外部系统的接口需要付费&#xff0c;一个接口一次调用付费 0.03 元 同一个月内&#xff0c;同一个接口最高付费 25 元 统计每个月的付费情况 需求清楚了不&#xff1f;不清楚&#xff1f; 给大家举个案例 这下明白了吧 明白了需求&…