Java基础-学习笔记14

news/2024/10/12 6:26:01

14 集合 Collection、Map

第一部分 Collection的框架体系

1) 可以动态保存任意多个对象,使用比较方便
2) 提供了一系列方便的操作对象的方法:add、remove、set、get等
3) 使用集合添加、删除新元素简单便捷。

集合 Collection 主要是两组:单列集合, 双列集合

  • List、Set是存储单列的数据集合,都继承与Collection接口。
  • Map 接口的实现子类是双列集合,存放 K-V,是个独立接口。

1. List接口

1) List 集合类中元素有序,且可重复。
2) List 集合中的每个元素都有其对应的顺序索引,即支持索引。
3) List 容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。

List 的三种遍历方式

1.1 ArrayList 底层结构和源码分析

1)ArrayList 中维护了一个 Object 类型的数组 elementData: transient Object[] elementData; // transient表示瞬间短暂的,表示该属性不会被序列化。

2)当创建 ArrayList 对象时,如果使用的是无参构造器,则初始 elementData容量为0,第1次添加,则扩容 elementData 为10,如需要再次扩容,则扩容 elementData 为1.5倍。( 0 -> 10 -> 15 -> 22 -> ...)

3)如果使用的是指定大小的构造器,则初始 elementData 容量为指定大小,如果需要扩容,则直接扩容 elementData 为1.5倍。

4) ArrayList 基本等同于 Vector,除了 ArrayList 是线程不安全(执行效率高),在多线程情况下,不建议使用 ArrayList。

1.2 Vector 底层结构和源码分析

1)Vector 底层也是一个对象数组, protected Object[] elementData;

2)Vector 是线程同步的,即线程安全,Vector 类的操作方法带有 synchronized。需要线程替补安全时,考虑使用 Vector。

1.3 LinkedList 底层结构和源码分析

1) LinkedList 底层实现了 双向链表双端队列特点,可以添加任意元素(可成都),包括 null。

2) 线程不安全,没有实现替补。

3) 维护了一个双向链表。维护了两个属性 first 和 last 分别指向 首节点和尾节点。每个节点(Node对象),里面又维护了 prev、next、item三个属性,其中通过 prev指向前一个,next指向后一个节点。最终实现双向链表。

4)所以 LinkList 的元素的添加和删除,不是通过数组完成的,相对来说效率较高。

2. Set接口

1) 无序、不能重复、可以添加 null。
2)Set 接口也是 Collection 的子接口,因此常用方法和 Collection 接口一样。
3)可以使用迭代器、增强for;不能使用索引的方式来获取。

2.1 HashSet 底层机制

  • 在执行 HashMap实例.add 方法后,会返回一个 boolean 值,如果添加成功,返回 true,否则 false。

  • HashSet不能添加相同的元素:

HashSet set = new HashSet();
set.add("0Mike"); // true
set.add("0Mike"); // false
set.add(new Person("1Jack")); // true
set.add(new Person("1Jack")); // true
set.add(new String("2King")); // true
set.add(new String("2King")); // false
  • HashSet 底层是 HashMap,HashMap 底层是 (数组 + 单向链表 + 红黑树)
  1. 在上面添加字符对象为例,调用equals 方法,由于字符类改写了改方法,比较的是字符串内容,因此将两个 “2King” 识别为相同对象,不添加。注:该 equals 方法是可以由程序员自行定义更改的。

2.1.1 LinkedHashSet 底层机制

1) LinkedHashSet 是 HashSet 的子类,LinkedHashSet 底层是一个 LinkedHashMap,底层维护了一个 数组+双向链表

2)LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。

  1. LinkedHashSet底层是 HashMap+ 双向链表
  2. 添加第一次时,直接将数组扩容到 16,存放的结点类型是LinkedHashMap$Entry。
  3. 数组是 HashMap$Node[],存放的元素/数据是 LinkedHashMap$Entry 类型。

3)LinkedHashSet 不允许添加重复元素。

第二部分 Map 接口

其实 Set 底层存放的也是 [K-V] 键值对形式,K 对应的就是存放的对象 Object,V 用多个是 PRESENT 这个常量替代,做占位作用。在 Map 里 K 也是存放的具体对象,V 则不再占位,由用户自己输入的具体对象。

  • Map 接口实现类的特点(JDK8)

1) Map 与Collection并列存在。用于保存具有映射关系的数据:Key-Value(双列元素)。
2) Map 中的 key 和value 可以是任何引用类型的数据,会封装到 HashMap$Node 对象中。
3) Map 中的 key 不允许重复,原因和HashSet一样,不过,当重复时,会进行替换操作,而不是放弃添加操作。Map 中的 value可以为重复。 key 和 value 可以为 null(为null 的 key 只能有一个)。
4) 常用 String 类作为 Map的 key。
5) key 和 value 之间存在单向一对一关系,即通过指定的 key总能找到对应的 value。
6) Map 存放数据的 key-value 示意图。一对 k-v 是放在一个 Node中的,又因为 Node 实现了 Entry 接口,有些书上也说一对 k-v 就是一个 Entry(如图)

  1. k-v 最后是 HashMap$Node node = new Node(hash key, value, null)
  2. k-v 为了方便程序员的遍历,还会创建 EntrySet 集合,该集合存放的元素类型 Entry, 而一个 Entry对象就有 k,v EntrySet<K, V>,即:transient Set<Map.Entry<K, V>> entrySet;
    (在entrySet里,只是让 K 指向了 Node 节点里的 key,V 指向了 Node节点里的 value;只是一个指向,并没有存放新的东西。这么做是为了遍历方便 )
  3. 在 enterSet 中,定义的类型是 Map.Entry,但是实际上存放的还是 HashMap\(Node。这是因为 HashMap\)Node implements Map.Enter接口,这里是向上转型(多态)。
  4. 当把 HashMap$Node 对象存放到 enterSet 就方便我们的遍历,因为 Map.Entry 提供了重要方法 K getKey(); V getValue();
  • Map 接口和常用方法
    遍历方式:① 增强for ② 迭代器 ③ 通过 entrySet

  • Map 接口的常用实现类
    HashMap、Hashtable、Properties

1. HashMap底层机制及源码剖析

HashMap没有实现同步,因此是线程不安全的,方法没有做同步互斥的操作,没有 synchronized。

2. HashTable

HashTable 是线程安全的。

2. Properties

1)Properties 类继承自 HashTable类并且实现了 Map接口,也是使用一种键值对的形式来保存数据。使用特点和HashTable类似。

2)pROPERRIES 还可用于从 xxx.properties 文件中,加载数据到 Properties 类对象,并进行读取和修改。

xxx.Properties 文件通常作为配置文件。

总结——开发中如何选择集合实现类

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Apache SeaTunnel技术架构演进及其在AI领域的应用

随着数据集成需求的增长,Apache SeaTunnel作为新一代的数据同步引擎,不仅在技术架构上不断演进,也在AI领域展现出其独特的应用价值。在CommunityOverCode Asia 2024大会上,Apache SeaTunnel PMC Chair 高俊 深入探讨SeaTunnel的技术演进路径,分析其在AI领域的应用案例,并…

Windows 系统 局域网文件夹共享无法访问的终极解决方法

先介绍 Win10 无法访问其他电脑的解决方法首先,Win10 能成功访问共享文件夹,必须有安装 SMB1 协议,否则会提示找不到网络名称的提示。 方法很简单,点击 微软小娜 Cortana 输入 启用或关闭 Windows 功能(或者直接输入 功能 也能找到),打开 启用或关闭 Windows 功能 对话框…

使用 updateAppConfig 更新 Nuxt 应用配置

title: 使用 updateAppConfig 更新 Nuxt 应用配置 date: 2024/8/27 updated: 2024/8/27 author: cmdragon excerpt: 通过使用 updateAppConfig,你可以轻松地在应用运行时更新配置,而无需重新启动应用。这对于需要在运行时调整设置的应用场景非常有用。 categories:前端开发…

AtCoder Beginner Contest 051

A - Haiku 直接模拟。 #include <bits/stdc++.h>using namespace std; using i64 = long long;int main() {ios::sync_with_stdio(false), cin.tie(nullptr);string s;cin >> s;string a, b, c;a = s.substr(0, 5);b = s.substr(6, 7);c = s.substr(14);cout <&…

PEP 508:为不同版本Python指定不同依赖

如果使用Python第三方包的某一个版本有问题,而不同版本Python所对应的软件最新版本又不一致,这种情况下如何在requirements.txt文件中指定软件最高版本是非常重要的。这里根据PEP 508的规范,做了一个Numpy版本要求numpy<=1.21.6 || 1.28>numpy>=1.23的示例。问题背…

经验分享|如何发现并利用信息泄露漏洞?

信息泄露漏洞是发现和报告的重要目标。虽然它们可能不会带来很丰厚的回报,但发现它们表明Web应用程序的安全性较差,这可能有助于发现更严重的漏洞。 一、常见的信息泄露漏洞类型 1.1服务器标识版本 服务器标识版本能够揭示服务器上运行的特定软件及其版本,这可以被用来寻找已…

简单萌萌哒 Top Tree(上)

前情提要。 Top Cluster 分解与 Top Tree 情景导入 我们总是想要以一种合适的方式对树进行划分,但是对于菊花图而言,基于点的划分总是不合适的,这启发我们基于边进行划分。事实上可以证明,基于边的划分总是可行的。 Top Cluster 分解就是一种基于边的划分方式,下面我们来介…

手把手教你—搭建Vue3企业级项目规范+基础封装配置

前言 如何搭建一个简易脚手架。核心需求是输入项目命令,clone准备好的项目模板,拉到本地后,装一下依赖,就可以直接开发了。不用每次都花大量时间,去搭建项目规范和做必要的封装配置。 经过简单寻找后,发现没有符合自己预期的。于是大雄从0到1搭建一个具备完善规范的Vue3开…