java容器学习总结(超赞!!!)

BLE天线设计避坑:NRF52832官方50欧姆阻抗匹配的3个常见误区 本文深入解析NRF52832蓝牙SoC天线设计中的常见误区,重点探讨50欧姆阻抗匹配的3个关键问题:PCB板材介电常数差异、匹配元件寄生参数及VSWR测试。通过实测数据和优化方案,帮助工程师规避设计陷阱,提升BLE通信性能。 阅读详情

我是技术搬运工,好东西当然要和大家分享啦.原文地址

概览

容器主要包括 Collection 和 Map 两种,Collection 又包含了 List、Set 以及 Queue。

1. List

  • ArrayList:基于动态数组实现,支持随机访问;

  • LinkedList:基于双向循环链表实现,只能顺序访问,但是可以快速地在链表中间插入和删除元素。不仅如此,LinkedList 还可以用作栈、队列和双端队列。

2. Set

  • HashSet:基于 Hash 实现,支持快速查找,但是失去有序性;

  • TreeSet:基于红黑树实现,保持有序,但是查找效率不如 HashSet;

  • LinkedListHashSet:具有 HashSet 的查找效率,且内部使用链表维护元素的插入顺序,因此具有有序性。

3. Queue

只有两个实现:LinkedList 和 PriorityQueue,其中 LinkedList 支持双向队列,PriorityQueue 是基于堆结构实现。

4. Map

  • HashMap:基于 Hash 实现

  • LinkedHashMap:使用链表来维护元素的顺序,顺序为插入顺序或者最近最少使用(LRU)顺序

  • TreeMap:基于红黑树实现

  • ConcurrentHashMap:线程安全 Map,不涉及类似于 HashTable 的同步加锁

5. Java 1.0/1.1 容器

对于旧的容器,我们决不应该使用它们,只需要对它们进行了解。

  • Vector:和 ArrayList 类似,但它是线程安全的

  • HashTable:和 HashMap 类似,但它是线程安全的

容器中的设计模式

1. 迭代器模式

从概览图可以看到,每个集合类都有一个 Iterator 对象,可以通过这个迭代器对象来遍历集合中的元素。

Java 中的迭代器模式

2. 适配器模式

java.util.Arrays#asList() 可以把数组类型转换为 List 类型。

 List list = Arrays.asList(1, 2, 3);
 int[] arr = {1, 2, 3};
 list = Arrays.asList(arr);

散列

使用 hasCode() 来返回散列值,使用的是对象的地址。

而 equals() 是用来判断两个对象是否相等的,相等的两个对象散列值一定要相同,但是散列值相同的两个对象不一定相等。

相等必须满足以下五个性质:

  1. 自反性
  2. 对称性
  3. 传递性
  4. 一致性(多次调用 x.equals(y),结果不变)
  5. 对任何不是 null 的对象 x 调用 x.equals(nul) 结果都为 false

源码分析

建议先阅读 算法 - 查找 部分,对集合类源码的理解有很大帮助。

源码下载:OpenJDK 1.7

1. ArraList

ArraList.java

实现了 RandomAccess 接口,因此支持随机访问,这是理所当然的,因为 ArrayList 是基于数组实现的。

public class ArrayList<E> extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable

基于数组实现,保存元素的数组使用 transient 修饰,这是因为该数组不一定所有位置都占满元素,因此也就没必要全部都进行序列化。需要重写 writeObject() 和 readObject()。

private transient Object[] elementData;

数组的默认大小为 10

public ArrayList(int initialCapacity) {
    super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
    this.elementData = new Object[initialCapacity];
}

public ArrayList() {
    this(10);
}

删除元素时调用 System.arraycopy() 对元素进行复制,因此删除操作成本很高,最好在创建时就指定大概的容量大小,减少复制操作的执行次数。

public E remove(int index) {
    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index, numMoved);
    elementData[--size] = null; // Let gc do its work

    return oldValue;
}

添加元素时使用 ensureCapacity() 方法来保证容量足够,如果不够时,需要进行扩容,使得新容量为旧容量的 1.5 倍。

modCount 用来记录 ArrayList 发生变化的次数,因为每次在进行 add() 和 addAll() 时都需要调用 ensureCapacity(),因此直接在 ensureCapacity() 中对 modCount 进行修改。

public void ensureCapacity(int minCapacity) {
    if (minCapacity > 0)
        ensureCapacityInternal(minCapacity);
}

private void ensureCapacityInternal(int minCapacity) {
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

在进行序列化或者迭代等操作时,需要比较操作前后 modCount 是否改变,如果改变了需要抛出 ConcurrentModificationException。

private void writeObject(java.io.ObjectOutputStream s)
    throws java.io.IOException{
    // Write out element count, and any hidden stuff
    int expectedModCount = modCount;
    s.defaultWriteObject();

    // Write out array length
    s.writeInt(elementData.length);

    // Write out all elements in the proper order.
    for (int i=0; i<size; i++)
        s.writeObject(elementData[i]);

    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }

}

和 Vector 的区别

  1. Vector 和 ArrayList 几乎是完全相同的,唯一的区别在于 Vector 是同步的,因此开销就比 ArrayList 要大,访问要慢。最好使用 ArrayList 而不是 Vector,因为同步完全可以由程序员自己来控制;
  2. Vector 每次扩容请求其大小的 2 倍空间,而 ArrayList 是 1.5 倍。

为了使用线程安全的 ArrayList,可以使用 Collections.synchronizedList(new ArrayList<>()); 返回一个线程安全的 ArrayList,也可以使用 concurrent 并发包下的 CopyOnWriteArrayList 类;

和 LinkedList 的区别

  1. ArrayList 基于动态数组实现,LinkedList 基于双向循环链表实现;
  2. ArrayList 支持随机访问,LinkedList 不支持;
  3. LinkedList 在任意位置添加删除元素更快。

2. Vector 与 Stack

Vector.java

3. LinkedList

LinkedList.java

4. TreeMap

TreeMap.java

5. HashMap

HashMap.java

使用拉链法来解决冲突。

默认容量 capacity 为 16,需要注意的是容量必须保证为 2 的次方。容量就是 Entry[] table 数组的长度,size 是数组的实际使用量。

threshold 规定了一个 size 的临界值,size 必须小于 threshold,如果大于等于,就必须进行扩容操作。

threshold = capacity * load_factor,其中 load_factor 为 table 数组能够使用的比例,load_factor 过大会导致聚簇的出现,从而影响查询和插入的效率,详见算法笔记。

static final int DEFAULT_INITIAL_CAPACITY = 16;

static final int MAXIMUM_CAPACITY = 1 << 30;

static final float DEFAULT_LOAD_FACTOR = 0.75f;

transient Entry[] table;

transient int size;

int threshold;

final float loadFactor;

transient int modCount;

从下面的添加元素代码中可以看出,当需要扩容时,令 capacity 为原来的两倍。

void addEntry(int hash, K key, V value, int bucketIndex) {
    Entry<K,V> e = table[bucketIndex];
    table[bucketIndex] = new Entry<>(hash, key, value, e);
    if (size++ >= threshold)
        resize(2 * table.length);
}

Entry 用来表示一个键值对元素,其中的 next 指针在序列化时会使用。

static class Entry<K,V> implements Map.Entry<K,V> {
    final K key;
    V value;
    Entry<K,V> next;
    final int hash;
}

get() 操作需要分成两种情况,key 为 null 和 不为 null,从中可以看出 HashMap 允许插入 null 作为键。

public V get(Object key) {
    if (key == null)
        return getForNullKey();
    int hash = hash(key.hashCode());
    for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
            return e.value;
    }
    return null;
}

put() 操作也需要根据 key 是否为 null 做不同的处理,需要注意的是如果本来没有 key 为 null 的键值对,新插入一个 key 为 null 的键值对时默认是放在数组的 0 位置,这是因为 null 不能计算 hash 值,也就无法知道应该放在哪个链表上。

public V put(K key, V value) {
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key.hashCode());
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}
private V putForNullKey(V value) {
    for (Entry<K,V> e = table[0]; e != null; e = e.next) {
        if (e.key == null) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }
    modCount++;
    addEntry(0, null, value, 0);
    return null;
}

6. LinkedHashMap

LinkedHashMap.java

7. ConcurrentHashMap

ConcurrentHashMap.java

探索 ConcurrentHashMap 高并发性的实现机制

参考资料

  • Java 编程思想
修复ASUS in WinRE教程 暑假入手了天选三,发现是win11家庭版,本来想着家庭版将就一下无所谓,结果在使用的过程中发现相较于专业版真的是不能比,于是自己就重装了系统,发现ASUS in WinRE入口不见了,折腾半天最后成功修复。 阅读详情

相关推荐

SpringCloud 2025王炸更新!GraalVM原生镜像启动速度提升90%实战

在当今云原生和Serverless架构盛行的时代,应用的启动速度已成为衡量技术栈竞争力的关键指标。传统SpringCloud应用由于依赖JVM的动态类加载、反射等机制,启动时间通常超过30秒,在Kubernetes滚动更新和函数计算场景下成为显著性能瓶颈。2025年,SpringCloud迎来里程碑式更新,通过深度集成GraalVM原生镜像技术,实现了启动速度提升90%的惊人突破,让SpringCloud应用正式进入"秒级启动"时代。

小筱在线博客 1099

Java容器总结

Java容器总结 本文参考:https://zhyan8.blog.youkuaiyun.com/article/details/99479065 1. 分类 容器框架简图 说明:紫色的为抽象类,无法实体化。蓝色的可以实体化。该图做了删减,只保留了一部分信息。 Java容器框架描述 Java Collections框架中包含了大量的接口及其实现类和操作他们的算法。主要有:List(列表)、Set(集合)、Map(映射)。 2. 描述 2.1 List 描述:按插入顺序保存对象(有序),允许元素重复。 1. Array

qq_45661953的博客 267

阿里巴巴达摩院人工智能训练师(高级)

阿里巴巴达摩院人工智能训练师(高级)

huang0612123的博客 1万+

JAVA容器全面总结

1 容器体系图 简图: 详图: 2 基础 2.1 Iterator接口 迭代器。 具有的能力:后向迭代、删除。 2.2 Iterable接口 表示一个类具有迭代能力。 提供能力:通过iterator()方法,返回iterator。 2.3 Collection接口...

dizi9750的博客 276

Centos7搭建OpenStack+创建iaas云主机

主要说明在控制节点和计算节点上,通过脚本的形式,安装OpenStack的iaas安装步骤和创建可运行的云主机。提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。

weixin_48218106的博客 1万+

FPGA实现Gardner环定时同步:Verilog代码与Testbench实战解析

本文深入解析了在FPGA上实现Gardner环定时同步的完整过程,详细阐述了其非数据辅助的定时误差检测原理。通过Verilog代码实战,展示了内插滤波器、定时误差检测器、环路滤波器和数控振荡器等核心模块的设计,并提供了完整的Testbench验证方法,帮助开发者解决数字通信系统中的时钟同步难题。

gpt4scribbler的博客 576

容器学习Day01-初识容器

随着容器技术的迅速发展,开发者已经由传统的虚拟机方式开始转向容器技术,为了适应潮流,咱也来学习一下,在这里记录下自己的学习笔记。以上就是今天学习了解的内容,后面准备虚拟机环境进行系统的学习。

AtobeKegio的博客 1455

SAP 未清PO数量 = 采购订单数量 - 已收货数量

本文介绍了SAP系统中查询未清PO数量的6种方法:1.标准采购报表(ME2L/ME2M/ME2N)适合业务用户快速查询;2.物料需求报表(MD04)可查看单个物料的供需情况;3.SQVI快速查询器提供自定义字段的灵活性;4.ABAP报表适合开发人员处理复杂逻辑;5.SAPQuery经配置后可供业务用户使用;6.BI/HANA方案适合大数据量分析。每种方法各有优缺点,用户可根据自身技术水平和具体需求选择,日常查询推荐使用标准采购报表ME2L/ME2M。

金牌架构师 1852

Java语言的容器化

近年来,容器化技术在软件开发和部署领域中得到了广泛应用。随着云计算的崛起和微服务架构的流行,容器化不仅极大地简化了应用的部署和管理,还提高了应用的可移植性和弹性。Java作为一种历久弥新的编程语言,其容器化的需求也随之增长。本文将深入探讨Java语言的容器化,从基础知识、技术栈、实践案例到最佳实践,为读者提供一个全面的视角。

2501_91525731的博客 1395

Python爬虫实战:构建高可用静态网页爬虫 - 以 Quotes 网站数据采集为例!

我长期专注 Python 爬虫工程化实战,主理专栏 《Python爬虫实战》:从采集策略到反爬对抗,从数据清洗到分布式调度,持续输出可复用的方法论与可落地案例。内容主打一个“能跑、能用、能扩展”,让数据价值真正做到——抓得到、洗得净、用得上。

喵手的博客 461

别再让 AI 瞎写 SAP 代码了!这套 Claude Code Skill 的验证机制才是关键

本文深入解析了专为SAP CAP开发设计的AI辅助工具sap-cap-capire的技术架构。该工具采用四层设计:协议层集成MCP和LSP实现实时模型访问与语法检查;智能层通过4个专业化Agent(数据建模、服务开发等)分工协作;验证层确保代码质量;知识层存储文档模板。这种工程化设计解决了通用AI在CAP开发中面临的上下文不足、专业性缺失和代码质量保证等核心问题,通过本地化服务和实时反馈机制显著提升了开发效率。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 882

【java笔记】java中的常用容器

java容器 1. 常用容器 java容器分为两大部分:Collection和Map。Collection是单个元素的集合,又可以分为List、Queue和Set。Map用来存储一组键值对,又可以分为HashMap和TreeMap。 2. List列表 List的特点就是所有的元素是可以重复的。 (1) ArrayList ArrayList是一个可以动态增长的数组, ArrayList由于底层是使用数组实现的,所以随机访问速度快,插入删除较慢。 (2) LinkedList LinkedList是使用链

zuzhiang的博客 7295

北斗导航:提高RTK定位精度的GIS应用

其中,RTK(Real-Time Kinematic)定位技术是一种实时差分定位技术,通过利用基准站的观测数据来对移动站的测量值进行差分处理,以提高定位精度。差分处理的关键是基准站的观测数据,基准站通过全球定位系统(如北斗导航系统)获取卫星信号并记录观测数据。通过使用RTK定位技术,结合北斗导航系统的观测数据和差分处理,可以实现高精度的定位结果。我们将介绍RTK定位的原理、使用北斗导航系统进行RTK定位的步骤,以及如何将定位结果与GIS数据进行集成和可视化展示。步骤1:设置基准站和移动站。

OvzStream的博客 475

10 种超赞的 MyBatis 写法!

foreach元素的属性主要有item,index,collection,open,separator,close。针对最后一条,我们来看一下官方说法:注意 你可以将一个 List 实例或者数组作为参数对象传给 MyBatis,当你这么做的时候,MyBatis 会自动将它包装在一个 Map 中并以名称为键。List 实例将会以“list”作为键,而数组实例的键将是“array”。所以,不管是多参数还是单参数的list,array类型,都可以封装为map进行传递。

weixin_72504091的博客 1073

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Java容器学习,一文读懂Java容器使用知识文集。

在 Java 中,容器通常指的是常用的数据结构集合,Java 提供了多种容器来存储、操作和访问数据。主要的 Java 容器包括以下几种......

m0_50308467的博客 1333

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Java容器有哪些?哪些是同步容器,哪些是并发容器?

Java容器有哪些?哪些是同步容器,哪些是并发容器?一、基本概念新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入...

u013030086的博客 6952

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

java容器都有哪些?

什么是容器? 容器是指用以容纳物料并以壳体为主的基本装置。摘自: 百度百科 java容器类类库的用途是"保存对象"。摘自: “Thinking in Java”. Java集合类是一种特别有用的工具类,可以用于存储数量不等的对象,并可以实现常用的数据结构,如栈,队列等.Java集合就像一种容器,可以把多个对象(实际上是对象的引用,但习惯上都称对象) “丢进” 该容器中. 摘自: “疯狂Java讲...

老狼的博客 1万+

java l1 034 点赞_L1-034 点赞

题目描述:微博上有个“点赞”功能,你可以为你喜欢的博文点个赞表示支持。每篇博文都有一些刻画其特性的标签,而你点赞的博文的类型,也间接刻画了你的特性。本题就要求你写个程序,通过统计一个人点赞的纪录,分析这个人的特性。输入格式:输入在第一行给出一个正整数N(≤1000),是该用户点赞的博文数量。随后N行,每行给出一篇被其点赞的博文的特性描述,格式为“K F ​1 ​​ ⋯F ​K ​​ ”,其中1≤K...

weixin_33900596的博客 478

Java初级工程师技能,超赞回答:Java如何进阶

一些看到我文章的朋友,问我怎么零基础Java“逆袭”,又怎么学好Java。以上算是我一些小小的经验,不说的多花里胡哨,就给一些跟我有过类似经历或者正在学习Java的朋友们一点经验之谈吧。希望能帮到你们。

2401_84408759的博客 751

Java并发学习之并发容器

上一篇博客主要学习了java中的同步容器,但在一些情况下,同步容器也会出现线程安全性的问题,如需要进行一些复合外部操作时,进行迭代时容易发生ConcurrentModificationException错误。 本篇博客主要学习一个相对于同步容器更好的容器集合:并发容器 一.并发容器 在Java 5.0后提供了多种并发容器类来改进同步容器的性能,它们所在的位置为:java.util.concurrent包中。 1.为何要引入并发容器? 我们知道,同步容器将所有对容器状态的访问都串行化来实现线程安全性,但这种方

c1776167012的博客 273

java点赞功能实现_JavaWeb中点赞功能的实现及完整实例

实现原理1、功能描述:一个用户对同一文章只能点赞一次,第二次就是取消赞2、建立一个点赞表great,字段有文章ID(aid),点赞用户ID(uid)3、当有用户进行点赞行为时,使用aid和uid搜索点赞表。若有该记录,则表示用户已经点过赞,本次点击是取消点赞行为,故删除great表中的该条记录,同时将该文章的点赞数减1。若无该记录,则表示用户是要点赞,故在great表中添加该记录,同时该文章的点赞...

weixin_42356284的博客 1466

Docker容器化Java程序

Docker容器化Java程序

wei_shuo的博客 1763

Java 容器梳理

Java 的容器框架是语言的核心组成部分,为开发者提供了存储、操作和检索数据的强大工具。本文梳理Java 容器的基础知识、框架结构、核心机制及实用注意事项。

YT的博客 1589

Java容器类学习心得

 Java容器类学习心得由于我对C++比较熟悉,所以学习Java应该重点体会Java带来的新概念。本文基本上是Java标准库中集合框架的基本概念,没有例子。写本文的目的在于方便我很长时间后若是忘了这些东西可以通过这片文章迅速回忆起来。1. 接口整个Java容器类的基础是容器接口(例如Collection,Map等接口),而不是类。使用接口的最大好处在于将容器的实现与容器的接口分开,这就

noot的专栏 1486

java 容器_Java容器框架学习整理

一:容器框架概述1.什么是容器2.Java 中的容器二:Collectoin 容器1.Collection 接口定义2.Collection 三个重要的子接口 List、Set、Queue3.List接口最重要的两个实现类 ArrayList 和 LinkedList4.Set 接口重要的实现类 HashSet5.Queue 接口介绍三:Map 容器1.Map 接口定义2.Map 重要的实现类 H...

weixin_40008920的博客 268

java实现点赞的原理_JavaWeb中点赞功能的实现及完整实例

实现原理1、功能描述:一个用户对同一文章只能点赞一次,第二次就是取消赞2、建立一个点赞表great,字段有文章id(aid),点赞用户id(uid)3、当有用户进行点赞行为时,使用aid和uid搜索点赞表。若有该记录,则表示用户已经点过赞,本次点击是取消点赞行为,故删除great表中的该条记录,同时将该文章的点赞数减1。若无该记录,则表示用户是要点赞,故在great表中添加该记录,同时该文章的点赞...

weixin_35280108的博客 1025
上一篇: java的I/O学习总结(超赞!!!)
下一篇: 面向对象思想学习总结(超赞!!!)
普通网友
博客等级 码龄9年 489粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值