首页 > 编程语言 >Java集合框架体系

Java集合框架体系

时间:2024-09-06 15:55:47浏览次数:5  
标签:Java HashMap 框架 ArrayList 元素 线程 集合 LinkedList

Collection

Map

Java集合类主要由两个接口Collection和Map派生出来的,Collection有三个子接口:List、Set、Queue。

  • Collection:最基本的集合接口,代表一组元素的集合。
    • List:代表有序的、可重复的元素。
    • Set:代表不可重复的的集合。
    • Queue: 代表队列
  • Map:存储键值对的集合,键不允许重复。

List 、Set、Queue、Map的区别

  • List:

    • 基于索引的集合,可以包含重复的元素。
    • 支持元素的有序存储,即元素插入的顺序就是它们在列表中的顺序。
    • 允许对元素进行快速随机访问。
    • 常见的实现类有 ArrayList、LinkedList
  • Set:

    • 不包含重复元素的集合。
    • 通常不保证元素的顺序,或者保证元素按照某种规则排序(如 TreeSet)。
    • HashSet 是基于哈希表实现的,不保证元素顺序;LinkedHashSet 维护元素插入的顺序;TreeSet 则根据元素的自然顺序或构造时提供的比较器对元素进行排序。
    • 常见的实现类有 HashSet、LinkedHashSet 和 TreeSet。
  • Queue:

    • 队列是一种特殊的集合,主要用于维护元素的顺序。通常按照先进先出(FIFO)的原则进行元素的插入和移除。
    • 支持元素的插入和移除操作,如 offer、poll、peek 等
    • 常见的实现类有LinkedList(先进先出FIFO)、PriorityQueue(优先队列)和 ArrayDeque。
  • Map

    • 存储键值对的集合,每个键最多只能映射到一个值。
    • 键必须唯一,而值可以重复。
    • 不保证元素的顺序,或者可以按照键或值的某种规则排序(如 TreeMap)。
    • 常见的实现类有 HashMap、LinkedHashMap、TreeMap

ArrayList与LinkedList的区别

1.底层数据结构:ArrayList基于动态数组实现;LinkedList基于(双向)链表实现。
2.随机索引访问:ArrayList的速度要优于LinkedList。因为ArrayList直接通过数组下标直接找到元素;LinkedList要移动指针遍历每个元素直到找到为止。
3.新增和删除元素:LinkedList的速度要优于ArrayList。因为ArrayList在新增和删除元素时,可能移动其它元素、扩容和复制数组;LinkedList除了实例化对象需要时间外,只需要修改指针即可。(LinkedList新增删除元素比ArrayList快的两个前提:1 往集合中间插入数据时ArrayList比linkedList慢 2 ArrayList正好扩容的时候添加数据要比LinkedList慢)
4.内存占用:ArrayList占用比LinkedList小,因为LinkedList的每个元素都需要存储额外的指针(prev 和 next)
5.线程安全:ArrayList与LinkedList都是非同步的,说明是非线程安全的,

特性 ArrayList LinkedList
内部结构 动态数组(基于数组实现) 双向链表(基于链表实现)
随机访问 快(O(1) 时间复杂度) 慢(O(n) 时间复杂度,需要遍历链表)
添加/删除 可能慢(特别是需要扩容时) 快(O(1) 时间复杂度,但在链表中间较慢)
内存占用 相对较小 相对较大(每个元素都需要额外的内存来存储指针)
扩容机制 当数组容量不足时自动扩容(JDK8,1.5倍) 不需要扩容
迭代器 快速且轻量级 相对较慢且占用更多内存
适用场景 频繁的随机访问 频繁的插入和删除操作

Arraylist 和 Vector 的区别

ArrayList在内存不够时,默认是1.5被扩展,Vector是默认扩展1倍。
ArrayList是非同步的。Vector是同步的,属于线程安全级别的。由于 Vector 的同步机制,它在性能上通常比 ArrayList 慢。
通常建议使用 ArrayList,因为它提供了更好的性能,并且在需要线程安全时,可以通过Collections.synchronizedList() 方法或使用 CopyOnWriteArrayList 类来实现。

HashMap

HashMap是一个散列表,它存储的内容是键值对(key-value)映射,根据键的HashCode值存储数据。HashMap 使用数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的, 链表长度大于8(TREEIFY_THRESHOLD)时,会把链表转换为红黑树,红黑树节点个数小于6(UNTREEIFY_THRESHOLD)时才转化为链表,防止频繁的转化。

示例:
hashcode是int型。提前了解,十进制转二进制,位运算符。

假设
第一步:h=10,
第二步:hash=10^(10>>>16)。

>>>是无符号右移运算。10的二进制是0000000000000000 0000000000001010。那么10>>>16,右移16位意味着丢弃最低的16位,结果是0。
^是异或运算,10^0结果还是10。

第三步:i = (n - 1) & hash

&是与运算。n默认是16。i=(16-1)&10结果是10。

因为第二步是取hashcode丢弃最低的16位的结果与hashcode进行按位异或运算,所以又被称为高16位运算
因为10&(16-1)=10%16,所以第三步又被称为取模运算
计算机中直接求余效率不如位移运算,hash%length==hash&(length-1)的前提是length是2的n次方,能均匀分布减少碰撞。

源码解析可以查看HashMap的put方法

  • 扩容机制(请阅读HashMap的resize方法)

    • 数组扩容
      当hashmap中的元素超过阈值(当前容量与负载因子的乘积),触发扩容。
      通过创建一个2倍当前容量的新数组,替换原数组来完成扩容。
      在此过程中需要重新计算每个键的哈希值,键值对需要重新映射

    • 链表扩容
      当链表长度超过一定阈值(TREEIFY_THRESHOLD,默认为8)时,链表会被转换为红黑树。
      当红黑树节点个数小于6(UNTREEIFY_THRESHOLD)时,红黑树会被转化为链表。

  • 红黑树

    红黑树是一种自平衡的二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。它具有以下特性:

    1.节点颜色:每个节点要么是红色,要么是黑色。
    2.根节点:根节点是黑色的。
    3.叶子节点:所有叶子节点(NIL节点,空节点)都是黑色的。
    4.红色节点的子节点:每个红色节点的两个子节点都是黑色的(不能有两个连续的红色节点)。
    5.路径黑色节点数:从根节点到任意叶子节点的路径上,黑色节点的数量相同。

    可结合HashMap里的TreeNode类理解。

HashMap和HashTable的区别

HashMap 和 Hashtable 都是 Java 中用于存储键值对的集合类,以下是它们的一些区别:

  • 继承关系:

    • Hashtable 继承自 Dictionary 类,而 Dictionary 类是 Java 的早期版本中的一个类,现在已经不推荐使用
    • HashMap 继承自 AbstractMap 类
  • 线程安全性:

    • Hashtable 是线程安全的,它的所有公共方法都是同步的,这意味着在多线程环境中,Hashtable 可以安全地使用而不需要额外的同步措施。
    • HashMap 是非线程安全的,如果在多线程环境中使用,需要外部同步或者使用 Collections.synchronizedMap 方法来包装它。
  • null 键和值:

    • Hashtable 不允许使用 null 作为键或值。
    • HashMap 允许使用一个 null 键和多个 null 值。

在实际应用中,由于 HashMap 提供了更好的性能和更灵活的使用方式,它通常是首选的 Map 实现。如果需要线程安全的 Map 实现,可以使用 ConcurrentHashMap,它是 Java 并发包中的一个线程安全 Map 实现,或者使用 Collections.synchronizedMap 方法来包装一个 HashMap。

HashMap与ConcurrentHashMap的区别

ConcurrentHashMap 和 HashMap 都用于存储键值对,以下是它们的以下区别:

  • 线程安全性

    • ConcurrentHashMap 是线程安全的
    • HashMap 是非线程安全的

HashSet

HashSet 实现了 Set 接口,它不允许集合中有重复的元素,并且不保证集合的迭代顺序;

以下是 HashSet 的一些关键特性:

  • 不允许重复

    HashSet 保证集合中每个元素都是唯一的。尝试添加已存在的元素将不会被添加。

  • 无序

    HashSet 不保证元素的顺序,这意味着每次迭代 HashSet 时元素的顺序可能不同。

  • 基于哈希表

    HashSet 内部使用哈希表实现,这使得添加、删除和查找元素的操作通常具有常数时间复杂度(即 O(1))。

  • 非同步

    HashSet 是非线程安全的。在多线程环境中,如果需要线程安全,可以使用 Collections.synchronizedSet 方法将其包装,或者使用 ConcurrentHashMap 作为替代。

当需要迭代顺序一致时,不应该使用 HashSet,而应该使用 LinkedHashSet。

TreeSet

TreeSet 实现了 Set 接口,它不允许集合中有重复的元素,并且保证了元素处于排序状态。TreeSet 基于红黑树(一种自平衡的二叉搜索树)实现,这使得它能够提供有序的数据集合。

以下是 TreeSet 的一些关键特性和用法:

  • 不允许重复

    TreeSet 不允许插入重复的元素。如果尝试添加已存在的元素,该元素不会被添加。

  • 有序

    TreeSet 保证了元素的迭代顺序是有序的,这使得它适合需要有序数据的场景。

  • 性能:

    TreeSet 的查找、插入和删除操作通常具有 O(log n) 的时间复杂度,其中 n 是集合中的元素数量。

  • 线程安全性:

    TreeSet 是非线程安全的。在多线程环境中,如果需要线程安全,可以使用 Collections.synchronizedSortedSet 方法将其包装,或者使用 ConcurrentSkipListSet。

TreeMap

TreeMap 实现了 Map 接口,它存储键值对并保证了键处于排序状态。TreeMap 基于红黑树(一种自平衡的二叉搜索树)实现,这使得它能够提供有序的数据集合。

以下是 TreeMap 的一些关键特性和用法:

  • 不允许重复键

    TreeMap 不允许插入重复的键。如果尝试添加已存在的键,那么旧的值将被新的值替换。

  • 有序

    TreeMap 保证了键处于有序状态,并且保证了元素的迭代顺序是有序的,这使得它适合需要有序数据的场景。

  • 性能:

    TreeMap 的查找、插入和删除操作通常具有 O(log n) 的时间复杂度,其中 n 是映射中的元素数量。

  • 线程安全性:

    TreeMap 是非线程安全的。在多线程环境中,如果需要线程安全,可以使用 Collections.synchronizedMap 方法将其包装。

参考

标签:Java,HashMap,框架,ArrayList,元素,线程,集合,LinkedList
From: https://www.cnblogs.com/fun-seeker/p/18396670

相关文章

  • java for循环倒序输出
    在Java中,如果你想使用for循环来实现倒序输出(比如倒序输出一个数组或集合中的元素,或者仅仅是从一个数字倒序输出到另一个数字),有几种方法可以实现。下面是一些常见的示例:示例1:倒序输出数组中的元素假设你有一个整数数组,并希望使用for循环来倒序输出数组中的每个元素。int[]numbers......
  • 数据结构练习题(java版)考前必备!
    今天我们刷一些栈队列的题目,大家还是先看题,后看题解。1.155.最小栈-力扣(LeetCode)思路:创建两个栈,一个栈所有元素都算,另一个栈只放小的元素,第二个栈中如果要放的元素比栈顶的元素小就放,这样我们直接pop第二个栈就能得到最小栈classMinStack{publicStack<Integer>......
  • 算法练习小技巧之有序集合--套路详细解析带例题(leetcode)
    前言:    本文详细讲解Python中的有序集合SortedList和C++中的有序集合multiset的用法,配合leetcode的例题来展示实际的用处。(本人水平不够,还无法讲解有序集合的实现方法,只会用)    觉得有帮助或者写的不错可以点个赞,后面也有几道我找出来的题目可以用这个方......
  • 基于Node.js+vue基于VUE框架搭建旅游网平台(开题+程序+论文) 计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容研究背景随着旅游业的蓬勃发展,人们对旅游体验的需求日益多元化和个性化。传统旅游网站在信息展示、交互体验及功能集成上已难以满足现代游客的期望。同时,Web前端开发......
  • JAVA三级分类的使用
    1.0准备1.创建好一个java文件2.导入所需要的包(至少29个)3.创建resources包并标记为资源根目录,配置好框架配置信息web.xml4.创建pojo包,编写实体类pojo 5.创建mapper包,编写接口mapper 6.编写实现类mapper.xml  7.创建service包,编写service以及impl8.编写测试......
  • 【Java】【SpringBoot】项目部署
    项目打包SpringBoot项目是依赖于Maven构建的,但打包时如果只依赖Maven打包工具则会打包不完整,我们还需要在SpringBoot项目中引入SpringBoot打包插件: 此时再使用Maven插件打包多环境配置在真实开发中,在不同环境下运行项目往往会进行不同的配置,比如开发环境使用的是开发数据库......
  • 【Java】【SpringBoot】读取配置文件(appliation.yml)的值
    这里叙述4中读取配置文件(application.yml)方法  application.yml配置如下:#测试数据(用于读取数据文件值)student:name:lisiage:13name:zhangsan使用@value注解@SpringBootTestpublicclassApplicationTest{@Value("${student.name}")privateStr......
  • 基于JavaWeb开发的Java+SpringBoot+vue+element实现前后端分离玩具商城系统
    基于JavaWeb开发的Java+SpringBoot+vue+element实现前后端分离玩具商城系统......
  • java webservice 带请求头方式处理
    1、gradle引入依赖的增强第三方包implementation'org.apache.cxf:cxf-spring-boot-starter-jaxws:3.2.6'2、增强类方法packagewebservice;importcom.alibaba.fastjson.JSON;importcom.landray.kmss.sys.notify.webservice.Exception_Exception;importcom.landray.......
  • JavaScript 导出csv
    1.修改指定列为中文可以通过遍历数据对象,将需要转换为中文的字段值替换为中文显示。2.删除不需要的列可以在导出数据之前,删除不需要的列(例如id列)。示例代码exportAsCSV(){//原始数据constdata=[{id:1,name:'JohnDoe',age:28,job:'Engineer'},......