【Java基础】集合容器

news2024/11/15 12:57:45

集合容器

文章目录

  • 集合容器
    • 1. 集合框架体系
    • 2. Collection子接口1:List
    • 3. Collection子接口2:Set
      • 3.1 Set主要实现类:HashSet
        • 3.1.1 HashSet概述
        • 3.1.2 HashSet中添加元素的过程:
        • 3.1.3 重写 hashCode() 方法的基本原则
        • 3.1.4 重写equals()方法的基本原则
      • 3.2 Set实现类之二:LinkedHashSet
      • 3.3 Set实现类之三:TreeSet
    • 4. Map接口
      • 4.1 Map接口概述
      • 4.2 Map中key-value特点
      • 4.3 Map的主要实现类:HashMap
      • 4.4 Map实现类之二:LinkedHashMap
      • 4.5 Map实现类之三:TreeMap
      • 4.6 Map实现类之四:Hashtable
      • 4.7 Map实现类之五:Properties
    • 5. Collections工具类

1. 集合框架体系

Java 集合可分为 Collection 和 Map 两大体系:

  • Collection接口:单列数据集合

    • List子接口:用来存储有序的、可以重复的数据(主要用来替换数组,"动态"数组)
      • 实现类:ArrayList、LinkedList、Vector
    • Set子接口:用来存储无序的、不可重复的数据
      • 实现类:HashSet、LinkedHashSet、TreeSet
  • Map接口:双列数据集合,存储key->value键值对

    • HashMap、LinkedHashMap、TreeMap、Hashtable、Properties

图示:集合框架全图

在这里插入图片描述

简图1:Collection接口继承树

在这里插入图片描述

简图2:Map接口继承树

在这里插入图片描述

2. Collection子接口1:List

实现类:

  1. ArrayList:“变长数组”,底层通过数组复制实现,顺序存储,查找效率高
  2. LinkedList:底层采用链表(双向链表)结构存储数据,对于频繁的插入或删除元素的操作,建议使用LinkedList类
    • 有特别的addFirst和addLast方法,可作为结构使用
  3. Vector古老的集合,大多数操作与ArrayList相同,区别之处在于Vector是线程安全的,效率较低,避免使用

即使需要线程安全的集合,也可通过Collections集合工具类方法获取,不要使用Vector集合

3. Collection子接口2:Set

3.1 Set主要实现类:HashSet

3.1.1 HashSet概述
  • HashSet 是 Set 接口的主要实现类,大多数时候使用 Set 集合时都使用这个实现类。底层使用HashMap实现,因此具有很好的存储、查找、删除性能

  • HashSet 具有以下特点

    • 不能保证元素的排列顺序
    • HashSet 不是线程安全的
    • 集合元素可以是 null
  • HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法得到的哈希值相等,并且两个对象的 equals() 方法返回值为true。

  • 存放在Set容器中的对象,对应的类一定要重写hashCode()和equals(Object obj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。

3.1.2 HashSet中添加元素的过程:
  • 第1步:当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法得到该对象的 hashCode值,然后根据 hashCode值,通过某个散列函数决定该对象在 HashSet 底层数组中的存储位置。

  • 第2步:如果要在数组中存储的位置上没有元素,则直接添加成功。

  • 第3步:如果要在数组中存储的位置上有元素,则继续比较:

    • 如果两个元素的hashCode值不相等,则添加成功;
    • 如果两个元素的hashCode()值相等,则会继续调用equals()方法:
      • 如果equals()方法结果为false,则添加成功。
      • 如果equals()方法结果为true,则添加失败。

第2步添加成功,元素会保存在底层数组中。

第3步两种添加成功的操作,由于该底层数组的位置已经有元素了,则会通过链表的方式继续链接,存储。

3.1.3 重写 hashCode() 方法的基本原则
  • 在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值。
  • 当两个对象的 equals() 方法比较返回 true 时,这两个对象的 hashCode() 方法的返回值也应相等。
  • 对象中用作 equals() 方法比较的 Field,都应该用来计算 hashCode 值。

注意:如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。

3.1.4 重写equals()方法的基本原则
  • 重写equals方法的时候一般都需要同时复写hashCode方法。通常参与计算hashCode的对象的属性也应该参与到equals()中进行计算。

  • 推荐:开发中直接调用Eclipse/IDEA里的快捷键自动重写equals()和hashCode()方法即可。

    • 为什么用Eclipse/IDEA复写hashCode方法,有31这个数字?
  首先,选择系数的时候要选择尽量大的系数。因为如果计算出来的hash地址越大,所谓的“冲突”就越少,查找起来效率也会提高。(减少冲突)
  
  其次,31只占用5bits,相乘造成数据溢出的概率较小。
  
  再次,31可以 由i*31== (i<<5)-1来表示,现在很多虚拟机里面都有做相关优化。(提高算法效率)
  
  最后,31是一个素数,素数作用就是如果我用一个数字来乘以这个素数,那么最终出来的结果只能被素数本身和被乘数还有1来整除!(减少冲突)

3.2 Set实现类之二:LinkedHashSet

  • LinkedHashSet 是 HashSet 的子类,不允许集合元素重复。
  • LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以添加顺序保存的。
  • LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。

在这里插入图片描述

3.3 Set实现类之三:TreeSet

  • TreeSet 是 SortedSet 接口的实现类,TreeSet 可以按照添加的元素的指定的属性的大小顺序进行遍历。
  • TreeSet底层使用红黑树结构存储数据
  • 新增的方法如下: (了解)
    • Comparator comparator()
    • Object first()
    • Object last()
    • Object lower(Object e)
    • Object higher(Object e)
    • SortedSet subSet(fromElement, toElement)
    • SortedSet headSet(toElement)
    • SortedSet tailSet(fromElement)
  • TreeSet特点:不允许重复、实现排序(自然排序或定制排序)
  • TreeSet 两种排序方法:自然排序定制排序。默认情况下,TreeSet 采用自然排序。
    • 自然排序:TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列。
      • 如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口。
      • 实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。
    • 定制排序:如果元素所属的类没有实现Comparable接口,或不希望按照升序(默认情况)的方式排列元素或希望按照其它属性大小进行排序,则考虑使用定制排序。定制排序,通过Comparator接口来实现。需要重写compare(T o1,T o2)方法。
      • 利用int compare(T o1,T o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
      • 要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。
  • 因为只有相同类的两个实例才会比较大小,所以向 TreeSet 中添加的应该是同一个类的对象
  • 对于 TreeSet 集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过 compareTo(Object obj) 或compare(Object o1,Object o2)方法比较返回值。返回值为0,则认为两个对象相等。

4. Map接口

4.1 Map接口概述

  • Map与Collection并列存在。用于保存具有映射关系的数据:key-value

  • Map 中的 key 和 value 都可以是任何引用类型的数据。但常用String类作为Map的“键”

  • Map接口的常用实现类:HashMapLinkedHashMapTreeMapProperties。其中,HashMap是 Map 接口使用频率最高的实现类

在这里插入图片描述

4.2 Map中key-value特点

这里主要以HashMap为例说明。HashMap中存储的key、value的特点如下:

在这里插入图片描述

  • Map 中的 key用Set来存放不允许重复,即同一个 Map 对象所对应的类,须重写hashCode()和equals()方法

在这里插入图片描述

  • key和value构成一个entry。所有的entry彼此之间是无序的不可重复的

4.3 Map的主要实现类:HashMap

  • HashMap是 Map 接口使用频率最高的实现类。
  • HashMap是线程不安全的。允许添加 null 键和 null 值。
  • 存储数据采用的哈希表结构,底层使用一维数组+单向链表+红黑树进行key-value数据的存储。与HashSet一样,元素的存取顺序不能保证一致。
  • HashMap 判断两个key相等的标准是:两个 key 的hashCode值相等,通过 equals() 方法返回 true。
  • HashMap 判断两个value相等的标准是:两个 value 通过 equals() 方法返回 true。

4.4 Map实现类之二:LinkedHashMap

  • LinkedHashMap 是 HashMap 的子类
  • 存储数据采用的哈希表结构+链表结构,在HashMap存储结构的基础上,使用了一对双向链表记录添加元素的先后顺序,可以保证遍历元素时,与添加的顺序一致。
  • 通过哈希表结构可以保证键的唯一、不重复,需要键所在类重写hashCode()方法、equals()方法。

4.5 Map实现类之三:TreeMap

  • TreeMap存储 key-value 对时,需要根据 key-value 对进行排序。TreeMap 可以保证所有的 key-value 对处于有序状态
  • TreeSet底层使用红黑树结构存储数据
  • TreeMap 的 Key 的排序:
    • 自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException
    • 定制排序:创建 TreeMap 时,构造器传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口
  • TreeMap判断两个key相等的标准:两个key通过compareTo()方法或者compare()方法返回0。

4.6 Map实现类之四:Hashtable

  • Hashtable是Map接口的古老实现类,JDK1.0就提供了。不同于HashMap,Hashtable是线程安全的。
  • Hashtable实现原理和HashMap相同,功能相同。底层都使用哈希表结构(数组+单向链表),查询速度快。
  • 与HashMap一样,Hashtable 也不能保证其中 Key-Value 对的顺序
  • Hashtable判断两个key相等、两个value相等的标准,与HashMap一致。
  • 与HashMap不同,Hashtable 不允许使用 null 作为 key 或 value

面试题:Hashtable和HashMap的区别

HashMap:底层是一个哈希表(jdk7:数组+链表;jdk8:数组+链表+红黑树),是一个线程不安全的集合,执行效率高
Hashtable:底层也是一个哈希表(数组+链表),是一个线程安全的集合,执行效率低

HashMap集合:可以存储null的键、null的值
Hashtable集合,不能存储null的键、null的值

Hashtable和Vector集合一样,在jdk1.2版本之后被更先进的集合(HashMap,ArrayList)取代了。所以HashMap是Map的主要实现类,Hashtable是Map的古老实现类。

Hashtable的子类Properties(配置文件)依然活跃在历史舞台
Properties集合是一个唯一和IO流相结合的集合

4.7 Map实现类之五:Properties

  • Properties 类是 Hashtable 的子类,该对象用于处理属性文件

  • 由于属性文件里的 key、value 都是字符串类型,所以 Properties 中要求 key 和 value 都是字符串类型

  • 存取数据时,建议使用setProperty(String key,String value)方法和getProperty(String key)方法

@Test
public void test01() {
    Properties properties = System.getProperties();
    String fileEncoding = properties.getProperty("file.encoding");//当前源文件字符编码
    System.out.println("fileEncoding = " + fileEncoding);
}
@Test
public void test02() {
    Properties properties = new Properties();
    properties.setProperty("user","songhk");
    properties.setProperty("password","123456");
    System.out.println(properties);
}

@Test
public void test03() throws IOException {
    Properties pros = new Properties();
    pros.load(new FileInputStream("jdbc.properties"));
    String user = pros.getProperty("user");
    System.out.println(user);
}

5. Collections工具类

参考操作数组的工具类:Arrays,Collections 是一个操作 Set、List 和 Map 等集合的工具类。

Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法(均为static方法):

排序操作:

  • reverse(List):反转 List 中元素的顺序
  • shuffle(List):对 List 集合元素进行随机排序
  • sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
  • sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
  • swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换

查找

  • Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
  • Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
  • Object min(Collection):根据元素的自然顺序,返回给定集合中的最小元素
  • Object min(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最小元素
  • int binarySearch(List list,T key)在List集合中查找某个元素的下标,但是List的元素必须是T或T的子类对象,而且必须是可比较大小的,即支持自然排序的。而且集合也事先必须是有序的,否则结果不确定。
  • int binarySearch(List list,T key,Comparator c)在List集合中查找某个元素的下标,但是List的元素必须是T或T的子类对象,而且集合也事先必须是按照c比较器规则进行排序过的,否则结果不确定。
  • int frequency(Collection c,Object o):返回指定集合中指定元素的出现次数

复制、替换

  • void copy(List dest,List src):将src中的内容复制到dest中
  • boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
  • 提供了多个unmodifiableXxx()方法,该方法返回指定 Xxx的不可修改的视图。

添加

  • boolean addAll(Collection c,T… elements)将所有指定元素添加到指定 collection 中。

同步

  • Collections 类中提供了多个 synchronizedXxx() 方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题:

在这里插入图片描述

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

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

相关文章

【Unity数据交互】JsonUtility的“爱恨情仇“

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

C++模拟实现-----日期计算器(超详细解析,小白一看就会!)

目录 一、前言 二、日期类计算器 三、日期计算器的实现 &#x1f34e;日期计算器各个接口的实现 &#x1f350;日期计算器的需求 &#x1f349;打印当前日期&#xff08;并检查日期是否合理&#xff09; &#x1f4a6;检查日期是否合理 &#x1f4a6;日期类构造函数&#x…

操作系统 (1)

进程的概念 进程同步/进程互斥 进程互斥的软件实现 进程互斥的硬件实现 信号量机制 生产者消费者问题 以下wei8最终情况,不可调换位置,否则会发生死锁 预防死锁 避免死锁

剖析C语言中的自定义类型(结构体、枚举常量、联合)兼内存对齐与位段

目录 前言 一、结构体 1. 基本定义与使用 2. 内存对齐 3. 自定义对齐数 4. 函数传参 二、位段 三、枚举 四、联合&#xff08;共同体&#xff09; 总结​​​​​​​ 前言 本篇博客将介绍C语言中的结构体&#xff08;struct&#xff09;、枚举&#xff08;enum&…

YOLOv8改进之C2f模块融合CVPR2023 SCConv

目录 1. SCConv SCConv模块的设计 SCConv模块的性能 2. YOLOv8 C2f融合SCConv模块 1. SCConv 卷积在各种计算机视觉任务中表现出色&#xff0c;但是由于卷积层提取冗余特征&#xff0c;其计算资源需求巨大。虽然过去用于改善网络效率的各种模型压缩策略和网络设计&#xff0c…

C++前缀和算法的应用:使数组相等的最小开销

本文涉及的基础知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 题目 给你两个下标从 0 开始的数组 nums 和 cost &#xff0c;分别包含 n 个 正 整数。 你可以执行下面操作 任意 次&#xff1a; 将 nums 中 任意 元素增加或者减小…

PCL 半径滤波剔除噪点

目录 一、算法原理二、注意事项三、代码实现一、算法原理 PCL半径滤波是删除在输入的点云一定范围内没有达到足够多领域的所有数据点。通俗的讲:就是以一个点p给定一个范围r,领域点要求的个数为m,r若在这个点的r范围内部的个数大于m则保留,小于m则删除。因此,使用该算法时…

arduino抢答器

按键传感器 &#xff1a; 1&#xff0c;如果按键传感器没有按下 他返回的值是1 2&#xff0c;如果按下 返回的值为0逻辑运算符有两种状态 True False 如果返回的是数字 0代表Fales 非0代表True 了解 比较运算和逻辑运算 如果两个传感器同时按下两个小灯才会亮 只要其中一…

【Android知识笔记】热修复专题

Android类加载与双亲委派知识回顾 Android 中的 ClassLoader 继承关系: 双亲委派模型: 在 Android 系统中,应用程序中默认的 ClassLoader 是 PathClassLoader 对象,即通过Context.getClassLoader()获取到的是一个 PathClassLoader 对象,而 PathClassLoader 对象的parent是…

[AUTOSAR][诊断管理][ECU][$22] 读取相关的数据

文章目录 一、简介$22服务的实际用途是什么?$22服务的应用场景有哪些呢?$22服务的诊断格式如何?常见DID总结请求实例服务响应负响应NRCNRC优先级二、示例代码uds22_read_data_by_ld.c一、简介 22服务作为诊断服务种的基础服务,可以简单理解为就是一个用于读取ECU数据的外部…

Redis(05)| 数据结构-哈希表

哈希表是一种保存键值对&#xff08;key-value&#xff09;的数据结构。 哈希表中的每一个 key 都是独一无二的&#xff0c;程序可以根据 key 查找到与之关联的 value&#xff0c;或者通过 key 来更新 value&#xff0c;又或者根据 key 来删除整个 key-value等等。 在讲压缩列表…

【torch高级】一种新型的概率学语言pyro(01/2)

一、说明 贝叶斯推理&#xff0c;也就是变分概率模型估计&#xff0c;属于高级概率学模型&#xff0c;极有学习价值&#xff1b;一般来说&#xff0c;配合实际活动学习可能更直观&#xff0c;而pyro是pytorch的概率工具&#xff0c;不同于以往的概率工具&#xff0c;只是集中于…

【咕咕送书 | 第四期】《ChatGPT 驱动软件开发:AI 在软件研发全流程中的革新与实践》

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《粉丝福利》 《C语言进阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 ⛳️ 写在前面参与规则一、前言1.0 人工智能新技术如何创新工作 &#xff1f; 二、内容简介三、作者简介四、专家推…

Makefile三个版本的编写

1.Makefile Makefile是一个工程管理文件&#xff0c;简化编译的流程&#xff0c;完成自动化编译的过程 在Makefile中&#xff0c;会把编译的过程分为两步&#xff0c;先生成.o文件&#xff0c;再对.o文件链接&#xff0c;生成可执行文件 Makefile由变量、函数、和规则构成 2.引…

Linux 系统调用IO口,利用光标偏移实现文件复制

用系统调用IO函数实现从一个文件读取最后2KB数据并复制到另一个文件中&#xff0c;源文件以只读方式打开&#xff0c;目标文件以只写的方式打开&#xff0c;若目标文件不存在&#xff0c;可以创建并设置初始值为0664&#xff0c;写出相应代码&#xff0c;要对出错情况有一定的处…

从入门到精通Ansible Playbook,一篇就够了

Playbook 一、Host Inventory(主机清单)1.1 简介1.2 inventory 文件1.2 inventory 中的变量 二、Playbook 剧本2.1 简介2.2 Playbook的组成部分2.3 如何编写Playbook&#xff1f;2.3.1 基本格式2.3.2 语句的横向/纵向写法 三、Playbook实例和知识点补充3.1 编写yum安装nginx的p…

si24r1/nrf24l01

Si24R1 可配置为 Shutdown、 Standby、 Idle-TX、 TX 和 RX 五种工作模式。 芯片上电后为shutdown模式。此模式下不可以通过芯片收发数据&#xff0c;但MCU和芯片可以通过spi协议通信&#xff0c;更改内部寄存器的状态&#xff08;如设置 CONFIG 寄存器下的 PWR_UP 位的值为 1&…

Java练习题2020 -1

统计1到N的整数中&#xff0c;被A除余A-1的偶数的个数 输入说明&#xff1a;整数 N(N<10000), A, (A 输出说明&#xff1a;符合条件的数的个数 输入样例&#xff1a;10 3 输出样例&#xff1a;2 (说明&#xff1a;样例中符合条件的2个数是 2、8) import java.util.Scanner;p…

Java SE 学习笔记(十四)—— IO流(3)

目录 1 缓冲流1.1 缓冲流概述1.2 字节缓冲流1.3 字符缓冲流 2 转换流2.1 字符输入转换流2.1 字符输出转换流 3 序列化3.1 对象序列化3.2 对象反序列化 4 打印流5 与Properties结合使用6 IO 框架 1 缓冲流 1.1 缓冲流概述 我们之前学习的字节流、字符流属于基础流、原始流&…

引流大法,助你销量翻倍!亚马逊新卖家必备的六种流量来源!

作为亚马逊的一个新卖家&#xff0c;我们在新店上传产品之后&#xff0c;第一个目标就是引流&#xff0c;因为流量是支撑店铺销量的重要环节&#xff0c;那么我们引流的方式都有哪些呢&#xff1f; ​首先我们要知道亚马逊的一些流量来源分别有哪几块&#xff01; 一、平台自…