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

Java 集合框架

时间:2023-07-10 11:34:52浏览次数:29  
标签:Java 框架 元素 value 链表 key 集合 数据

Java 集合框架

Java 集合框架是每一个入门开发者必会的内容,而且在较长的时间内容,不管是使用还是面试频度否非常的高,所以本人认为完全的、深入的学习是十分有必要的。本人结合源码和网络上的相关文章进行了总结。

<iframe frameborder="0" height="500" leftmargin="0" scrolling="No" src="https://www.processon.com/embed/64301356ac665635d267cccc" topmargin="0" width="100%"></iframe>

Collection

Collection 是 ListSet的父类,它抽象了单列数据集合的基本方法。它包含了以下的方法:

  1. int size():获取单列数据集合中存储数据的数量
  2. isEmpty():当前单列数据集合是否为空
  3. contains(Object o): 当前单列数据合计是否存在该数据对象,当前对象需要实现 equalshashCode 方法,防止不同的对象校验的 hashCode 一致
  4. toArray(): 单列数据集合转数组
  5. toArray(T[]) :单列数据结合转数组,数组类型为参数类型
  6. add(E e): 单列数据集合添加数据
  7. remove(E e): 删除单列数据集合中的该数据
  8. containsAll(Collection<?> c): 校验当前数据集合是否在该单列数据中,若都存在则返回 true
  9. addAll(Collection<?> c): 向当前单列数据集合中添加该数据结合
  10. removeAll(Collection<?> c): 当前单列数据集合中移出指定的数据集合
  11. removeIf(Predicate<? super E> filter): 移出通过 filter 筛选的数据集合
  12. retainAll(Collection<?> c): 从该集合中删除未包含在指定集合中的所有元素
  13. clear(): 从此集合中移除所有元素(可选操作)。该方法返回后,集合将为空。
  14. equals(Object o):
  15. hashCode():
  16. spliterator():
  17. stream():
  18. parallelStream():

实现类比较

实现类名称 实现原理 优点 缺点
ArrayList 数组 索引查询快 变更效率低
LinkedList 链表 变更效率高 索引查询慢
Vector ArrayList 一致 加锁,防止并发问题 由于加锁问题,导致操作效率较低
Stack 继承了 Vector 相比于 Vector 功能更加强大,封装了部分方法 和 Vector 一致

ArrayList

ArrayListCollection 实现子类,它实现了 Collection 的所有功能且添加了部分自己独有的一些功能,让其使用更加方便和简单。内部的实现原理是通过数组进行缓存元素数据,通过 size 属性缓存数据的长度。

构造方法

ArrayList 有三个构造方法,无参、初始容量、初始元素。

  • 无参:会给属性 this.elementData赋值为DEFAULTCAPACITY_EMPTY_ELEMENTDATA
  • 初始容量:若设置容量大于 0,会给属性 this.elementData赋值为new Object[initialCapacity];若设置容量等于 0 ,会给属性 this.elementData赋值为EMPTY_ELEMENTDATA;若设置容量小于 0,则抛出异常。
  • 初始元素:若初始元素数量等于 0, 则会给属性 this.elementData赋值为EMPTY_ELEMENTDATA;若初始元素数量大于 0,则会把元素赋值给this.elementData

判断

判断集合中是否存在该元素是通过遍历集合的属性elementData的数据,通过equals判断数据是否相等,所以需要该数据对象实现对应的方法。

新增

添加元素时先让modCount 加一(后续移出时会使用)。如果当前插入的位置等于元素数量即当前集合数据已满,则需要进行扩容,扩容代码如下:

    private int newCapacity(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity <= 0) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
                return Math.max(DEFAULT_CAPACITY, minCapacity);
            if (minCapacity < 0) // overflow
                throw new OutOfMemoryError();
            return minCapacity;
        }
        return (newCapacity - MAX_ARRAY_SIZE <= 0)
            ? newCapacity
            : hugeCapacity(minCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE)
            ? Integer.MAX_VALUE
            : MAX_ARRAY_SIZE;
    }
  • minCapacity: 是当前容量+1
  • newCapacity: 是 oldCapacity + (0.5*oldCapacity)

    第一次扩容时,若是无参的构造方法,则会进行默认为容量是 10;含有参数的构造方法,第一次则按照 1.5 倍扩容(初始化容量为 0 时,则第一次扩容容量会变更为 1)

    后续扩容,则需要判断扩容 1.5 倍之后是否超出 int 的最大值,若是会超过则取 Integer.MAX_VALUE

删除

单个删除时:查询元素在集合的下标索引,然后通过System.arraycopy进行数组的 copy 和创建以此实现数据的删除

批量删除时: 会缓存modCount 在删除的过程中会校验缓存的modCount是否和当前的一致,若是不一致则会抛出ConcurrentModificationException异常,提示在并发修改

扩展方法

LinkedList

LinkedList 也是实现Collection 的子类,它内部的数据接口是采用链表的方式进行存储,数据长度也是通过属性进行获取的。

构造方法

该类的构造方法并未进行特殊的处理,无参的构造方法什么都为进行初始化,通过集合进行初始化的,则直接调用的addAll

判断

这里判断对象是否存在也是进行数据遍历,进行比较数据对象是否存在。

新增

刚创建时,属性firstlast 都是空的,第一次添加是会给 firstlast 赋值,后续创建则直接在先缓存 last 然后 last等于新元素,缓存的last关联新元素,从而先新元素的添加。

删除

删除则是查询到对应的节点后,直接让前一个节点关联后一节点,从而实现该节点的删除。

扩展方法

Vector

Vector 类似于 ArrayList 都是基于数组的存储结构,只不过加入了自己特性的一些东西,例如扩容规则、线程安全。

构造方法

构造方法可以传入初始容量和扩容自增的数量。默认的初始容量是 10,自增的属性值设置为 0。

判断

基本和ArrayList 一致,只不过在判断时加锁进而防止并发问题。

新增

新增操作和ArrayList一致,只不过在操作的时候添加了锁,进行防止并发操作

删除

扩展方法

Stack

HashSet

TreeSet

CopyOnWriteArrayList

CopyOnWriteArraySet

ConcurrentSkipListSet

Map

Map 抽象了键值对数据集合的通用方法,它包含以下方法:

  1. int size():查看元素数目
  2. isEmpty():元素个数是否是0
  3. containsKey(Object key):是否存在这个 key
  4. containsValue(Object value): 是否存在个 value
  5. get(Object key): 通过 key 获取对象的 value
  6. put(K key, V value): 添加 key-value 元素
  7. remove(Object key): 移出 key 对应的 value
  8. putAll(Map<? extends K, ? extends V> m):添加集合中的所有元素
  9. clear(): 清空元素
  10. keySet(): 获取元素的 key 的不重复集合
  11. values():获得元素中的所有 value
  12. entrySet():获取所有的 key-value 对象
  13. getOrDefault(Object key, V defaultValue):获取 key 对应的 value,若不存在在返回 defaultValue
  14. putIfAbsent(K key, V value): 若是不存在 key 对应的 value 则进行添加
  15. remove(Object key, Object value):删除 key 对应的值且等于 value 的
  16. replace(K key, V oldValue, V newValue): 若存在 key 的值为 oldValue 的元素,则重新赋值 key 的值为 newValue
  17. replace(K key, V value):若存在 key 就添加 key 对应的值为 value
  18. computeIfAbsent(K key,Function<? super K, ? extends V> mappingFunction):若不存在 key 对应的值,则通过 mappingFunction 获取,且添加到集合中
  19. computeIfPresent(K key,BiFunction<? super K, ? super V, ? extends V> remappingFunction):若是存在key 对应的 value 则传入 key,value 到 mappingFUnction 获取新的 newValue,若 newValue 为空则会清除 key,若不为空,则修改集合中key 对应的值,且返回newValue

HashMap

HashMap 通过设置一些属性,进行控制某些行为,例如:初始容量、扩容时下次数量、多少元素转化为树,以下是 HashMap 的属性:

  • DEFAULT_INITIAL_CAPACITY = 1 << 4; 初始容量为 16
  • MAXIMUM_CAPACITY = 1 << 30; int 的最大值为 2 的 31-1,但是只能移动1 所以最大值为 2 的 30 次方
  • DEFAULT_LOAD_FACTOR = 0.75f; 默认的负载因子 0.75
  • TREEIFY_THRESHOLD = 8; 链表树化的最小元素数量,即链表元素个数大于 8 时,链表进行树化
  • UNTREEIFY_THRESHOLD = 6; 树退化成链表的最大元素数量,当树的元素数量小于 6 的时候,树退化为链表
  • MIN_TREEIFY_CAPACITY = 64; 集合树化的最小元素个数,当集合元素数目大于 64 的时候才可能树化,优先级大于 TREEIFY_THRESHOLD ,可以存在链表长度大于 8 ,只有当容量大于 64 才会树化
  • Node<K,V>[] table; 集合元素数据
  • Set<Map.Entry<K,V>> entrySet; 缓存的数据
  • int size; 元素数目
  • int modCount; 防止迭代器遍历的时候修改
  • int threshold; 下一次扩容的容量
  • float loadFactor; 负载因子

HashMap的扩缩容

当进行新增时,会先去取 key 的哈希值, (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16),进行 put 时,会先进行判断 table 是否存在数据,如果没有则调用 resize() 进行初始化或扩容,若 该元素在 table 中不存在哈希冲突则放置到对应的下标上,若存在哈希冲突则需要判断 table 该下标的数据是否是树,若是树则进行添加子节点,若不是树,则链接在链表后,判断若当前链表的数量大于默认树化的数目,则执行 treeifyBin(tab, hash),进行树化处理

  • 为什么要这么计算哈希值

TreeMap

WeakHashMap

Hashtable

ConcurrentHashMap

ConcurrentSkipListMap

Queue

ArrayBlockingQueue

LinkedBlockingQueue

LinkedBlockingDeque

ConcurrentLinkedQueue

ConcurrentLinkedDeque

标签:Java,框架,元素,value,链表,key,集合,数据
From: https://www.cnblogs.com/jiuxialb/p/17540465.html

相关文章

  • Java 并发
    Java并发线程基础进程线程概念进程是一个独立的运行环境,而线程是在进程中执行的一个任务。他们两个本质的区别是是否单独占有内存地址空间及其它系统资源(比如I/O):进程单独占有一定的内存地址空间,所以进程间存在内存隔离,数据是分开的,数据共享复杂但是同步简单,各个进程之间互......
  • JavaCV实现旋转图像识别和旋转角度预测
    引言本文将介绍如何使用JavaCV库来实现图像识别和旋转角度预测,并结合直方图统计和dhash算法来比较图片的相似度。JavaCV是一个基于OpenCV的Java库,提供了丰富的图像处理和计算机视觉功能。环境搭建在开始之前,需要安装JavaCV库和相关依赖。可以通过Maven或手动下载jar包的方式进......
  • Blazor前后端框架Known-V1.2.3
    V1.2.3Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行。Gitee:https://gitee.com/known/KnownGithub:https://github.com/known/Known概述基于C#和Blazor实现的快速开发框架,前后端分离,开箱即用。跨平台,单页应用,混合桌面应用,Web和桌面......
  • 如何实现java Docker Engine API的具体操作步骤
    使用Java实现DockerEngineAPI引言Docker是一款非常流行的容器化平台,它可以让开发者更方便地构建、交付和运行应用程序。Docker提供了一系列的API,用于管理和操作Docker引擎,通过这些API可以实现容器的创建、启动、停止等操作。本文将向你介绍如何使用Java来实现DockerEngineAPI......
  • java项目 报错 maven jdk.tools 缺失 解决方法
    一、解决方法配置文件pom.xml<dependency><groupId>jdk.tools</groupId><artifactId>jdk.tools</artifactId><version>1.7</version><scope>system</scope><systemPath>${......
  • java实现上传zip解压及判断压缩包文件夹功能
    直接上Service,通过代码看思路贯穿整个功能,很多工具类可以复用,文件路径可以去看我博客里的(使用ResourceBundle国际化资源文件读取properties详解) 这篇制作方法url:html页面<span>ZIP:</span><inputtype="file"style="width:170px"name="hostFileBatch"/><spanid="host......
  • Java获取名字首字母拼音及用户按名字拼音分组工具
    一、需求分析最近在做一个类似于微信用户通讯录的功能,所以考虑通过查找的好友列表,在后台遍历按照26个字母分组,前台获取到Json循环26个字母直接解析对应的字符下的名称为一组分隔,没有则不显示,工具如下↓二、引入Pom<dependency> <groupId>com.belerweb</groupId> <artif......
  • Java大厂面试必考真题算法篇(持续更新)十一、java 统计字符串中每个字符出现的次数
    一、写出一个程序,接受一个字符串,然后输出该字符串反转后的字符串。答案importjava.util.*;publicclassSolution{/***反转字符串*@paramstrstring字符串*@returnstring字符串*/publicStringsolve(Stringstr){if(str......
  • java使用百度翻译接口实现前后端翻译功能
    java 百度翻译工具类 分别有前端和后端的 例子及工具使用百度翻译接口需要网上申请key,代码里面有URL。packagecn.secure.util;importjava.io.BufferedReader;importjava.io.Closeable;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStrea......
  • P1551 亲戚 && #569. 【例4-7】亲戚(集合)
    P1551亲戚题目链接:落谷题目链接:TFLSOJ落谷题解(具体分析见慎入潜出P239)#include<bits/stdc++.h>usingnamespacestd;intn,m,p;intfu[5010];intfind(intx){//查询是否是同一个家族 if(x==fu[x]) returnx; returnfu[x]=find(fu[x]);}voidconnect(intx,inty){......