[java] 深度解析容器

36、Java 容器与迭代器深度解析 本文深入解析了Java中的容器与迭代器,涵盖了ArrayList、LinkedList、集合等常见容器的特点与适用场景,详细介绍了迭代器的使用方法及其优势与局限。通过示例代码展示了容器的基本操作、迭代器的遍历逻辑以及如何选择合适的容器类型。此外,还讨论了容器操作的最佳实践和代码优化建议,帮助开发者更高效地使用Java容器与迭代器。 阅读详情

容器,和我们平常说的集合是指的一个概念。

为什么需要容器

如果一个程序只包含固定数量的且其生命期都是已知的对象,那么这是一个非常简单的程序。

但是通常,程序问题根据运行时才知道的某些条件支创建新对象。在此之前,不会知道所需对象的数量,甚至不知道确切的类型。这是一个编程语言设计角度的问题,为了解决这个普遍的编程问题,需要在任意时刻任意位置创建任意数量的对象。不能依靠创建命名的引用来持有每一个对象,如:

MyType aReference;

从这个角度来讲,这个问题不仅是java需要关注的问题也是所有编程语言需要关注的问题,而大多数语言都提供了某种方法来解决这个基本问题。

java有多种方式保存对象(更准确的说是保存对象的引用)。比如数组。但数组具有固定的尺寸。但是我们写程序是往往是无法预知有多少个对象的。java容器类库提供了一套相当完整的容器类来解决这个问题,其中最基本的类型是List,Set,Queue和Map。它们各自有自己的特点。

我们使用了Collection容器这个范围更大的术语称呼它们。

基本概念

java集合类库的用途是保存对象。java体系里的集合从继承关系来看可分为两个部分,一个是Map接口下的,另一个是Collection下的。

Map  

一组成都的键值对对象,允许使用键来查找值。映射表允许我们使用一个对象来查找另一个对象,它也被称为关联数组,因为它将某些对象与另外一些对象关联在了一起,或者被称为字典,因为你可以用键对象来查找值对象,就像在字典中查单词一样。Map是强大的编程工具。

两个接口下的实现类,接口非常之多。在JDK1.8中,Map的一级子类大概如下:

注意,这里仅仅是一级子类,他们下面还有许多实现类,想全部弄懂是一件不可能的事情也是没有必要的事情。下面我将map下面较为常见的类和接口做了一个总结,他们的关系如下:

灰色:接口interface

橙色:类class

我们常见的HashMap,ConcurrentHashMap,HashTable和TreeMa都已经包括在了其中。他们分别的实现可以参考我的另一篇博文:链接。

Collection 

一个独立元素的序列序列,这些元素都服从一条或多条规则。比如List必须按照插入的顺序保存元素,而Set不能有重复元素,Queue按照排队规则来确定对象的顺序。

Collection的一级子类在这里不再列出来。同样我们将Collection下面常用的类做一个总结,其结构如下:

很有意思的现象是和map相比,

  1. Collection在最上层就继承了Iterable接口,这意味着从设计的角度来讲,整个Collection架构都是设计为可被用于遍历循环的。
  2. Collection在定义的时候就有一个参数<E>,而Map在定义的时候参数即为<K,V>,这其实意为着在设计之处,整个Map架构就是用于键值对,key-value这样的模式,而Collection这是一个纯粹的容器,可以放任何的对象并且对他们进行批量操作
  3. 这个图不完全准确,但是大体的架构和继承关系是正确的。仅供参考。

 Collection的功能方法

下面的表格列出了可以通过Collection执行的所有操作(不包括从Object继承而来的方法)。因此,它们也是可通过Set或List执行的所有操作(List还有额外的功能)

请注意,其中不包括随机访问所选择元素的get()方法。因为Collection包括Set,而Set是自己维护内部顺序的(这使得随机访问变得没有意义)。因此,如果想检查Collection中的元素,那就必须使用迭代器。

 

各种容器的特点

1)数组将数字与对象联系起来。它保存类型明确的对象,查询对象时,不需要对结果做类型转换。它可以是多维的,可以保存基本数据类型的数据。但是,数组一旦生成,其容量就不能改变。

2)Collection保存单一的元素,而Map保存相关联的键值对。有了Java的泛型,你就可以指定容器中存放的对象类型,因此你就不会将错误类型的对象放置到容器中,并且在从容其中获取元素时,不必进行类型转换。各种Collection和各种Map都可以在你向其中添加跟多的元素时,自动调整其尺寸。容器不能持有基本类型,但是自动包装机制会仔细地执行基本类型到容器中所有的包租昂其类型之间的双向转换。

3)像数组一样,List也建立数字索引与对象的关联,因此,数组和List都是排好序的容器。List能自动扩充容量。

4)如果要进行大量的随机访问,就用ArrayList;如果经常从表中间插入或删除元素,则应该使用LinkedList。

5)各种Queue以及栈的行为,有LinkedList提供支持。

6)Map是一种将对象(而非数组)与对象相关联的设计。HashMap设计用来快速访问;而TreeMap保持“键”始终处于排序状态,所以没有HashMap快。LinkedListHashMap保持元素插入的顺序,但是也通过散列提供了快速访问的能力。

7)Set不接受重复元素。HashSet提供最快的查询速度,而TreeSet保持元素处于排序状态。LinkedHashSet以插入顺序保持元素。

8)新程序中不应该使用过时的Vector、Hashtable和Stack。

 

添加一组元素

Arrays.asList方法接受一个数组或是一个用逗号分割的元素列表,它使用可变参数,并将其转换为一个List对象。

Collections.addAll方法接受一个Collection对象,以及一个数组或是一个由逗号分割的列表,将元素添加到Collection中。

下面的代码是一个使用演示:

public class AddingGroups {
    public static void main(String[] args) {
        Collection<Integer> collection = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
        Integer[] moreInts = {6, 7, 8, 9, 10};

        collection.addAll(Arrays.asList(moreInts));

        Collections.addAll(collection, 11, 12, 13, 14, 15);
        Collections.addAll(collection, moreInts);

        List<Integer> list = Arrays.asList(16, 17, 18, 19, 20);
        list.set(1, 99);//modify an element
    }
}

List接口在Collection的基础上添加了大量的方法,使得可以在List中间插入和删除元素。

有两种类型的List:

ArrayList,它长于随机访问元素,但是在List的中间插入和移除元素的时候较慢。

LinkedList,它在List中间进行插入和删除的操作代价较低,但是在随机访问方面相对较慢,但是它的特性集比ArrayList更大。

关于这两个类的详细信息,请参考我的文章: [java] ArrayList和LinkedList实现原理及比较.

迭代器

迭代器,也是一种设计模式。迭代器是一个对象,它的工作遍历并选择序列中的对象,而程序员不用关心该序列底层的结构。迭代器通常被称为轻量级对象,创建它的代价小。java的Iterator只能单向移动,这个Iterator只能用来:

  1. 使用方法iterator()要求容器返回一个Iterator。Iterator将准备好返回序列中的第一个元素。
  2. 使用next()获得序列中的下一个元素
  3. 使用hasNext()检查序列中是否还要元素
  4. 使用remove()将迭代器新返回的元素删除

这四个功能中的后三个方法和Iterator这个接口定义的几个方法都是一一对应:

/**
     * Returns {@code true} if the iteration has more elements.
     * (In other words, returns {@code true} if {@link #next} would
     * return an element rather than throwing an exception.)
     *
     * @return {@code true} if the iteration has more elements
     */
    boolean hasNext();

    /**
     * Returns the next element in the iteration.
     *
     * @return the next element in the iteration
     * @throws NoSuchElementException if the iteration has no more elements
     */
    E next();

    /**
     * Removes from the underlying collection the last element returned
     * by this iterator (optional operation).  This method can be called
     * only once per call to {@link #next}.  The behavior of an iterator
     * is unspecified if the underlying collection is modified while the
     * iteration is in progress in any way other than by calling this
     * method.
     *
     * @implSpec
     * The default implementation throws an instance of
     * {@link UnsupportedOperationException} and performs no other action.
     *
     * @throws UnsupportedOperationException if the {@code remove}
     *         operation is not supported by this iterator
     *
     * @throws IllegalStateException if the {@code next} method has not
     *         yet been called, or the {@code remove} method has already
     *         been called after the last call to the {@code next}
     *         method
     */
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

但是第一个功能:使用方法iterator()要求容器返回一个Iterator。在Iterator接口里面却找不到定义。我们需要从Iterator这个接口和容器的关系着手研究这个问题。

Collection和Iterator是组合的关系。

这意味着在Collection容器中会持有一个Iterator的引用,事实上也确实如此,Collection中的代码如下:

 /**
     * Returns an iterator over the elements in this collection.  There are no
     * guarantees concerning the order in which the elements are returned
     * (unless this collection is an instance of some class that provides a
     * guarantee).
     *
     * @return an <tt>Iterator</tt> over the elements in this collection
     */
    Iterator<E> iterator();

 

深度解析Java容器化:自动化部署与扩展的艺术 在现代软件开发的世界里,容器技术已经成为推动应用快速迭代、高效运维的关键因素。尤其是对于Java开发者来说,掌握如何将应用程序容器化,并实现自动化的部署和扩展,不仅能够大幅提升开发效率,还能确保服务的高可用性和可伸缩性。本文将深入探讨如何利用Docker和Kubernetes等工具,结合Jenkins实现Java应用的自动化部署与扩展,带你领略容器化技术的魅力。 阅读详情

相关推荐

SDFCOM_SWC警告深度剖析:从assign短路到时序标注失效的链路追踪

本文深入剖析了SDFCOM_SWC警告的根源,从assign短路到时序标注失效的全链路追踪。通过分析RTL设计中的assign语句陷阱、综合阶段的优化变形以及PrimeTime生成SDF文件的视角,提出了重构RTL设计、警告抑制和SDF生成优化等解决方案,帮助工程师有效避免时序标注问题。

weixin_42519985的博客 363

【开源分享】容器内的top命令工具

考虑到部署lxcfs有一定的成本,topic(top in container)的思路则是改造top命令,去适配容器,读取容器中反映真实运行情况的系统文件,从而展示正确的容器运行信息,对于用户而言成本更低。针对容器内查看系统状态的问题,目前比较通用的解决方案是通过lxcfs,将容器中相应的文件通过fuse劫持read调用,在打开时显示为容器信息,从而统一解决各种系统状态诊断工具的问题。topic 即 top in container的缩写,意味容器内的top命令。现在的cpu和内存都是容器自己的。

云胜的笔记 993

傅里叶光学(1)

傅里叶光学,可以看作是通信理论中傅里叶变换等一系列数学思想以及系统理论与光学(主要是衍射光学)相结合的产物关于傅里叶光学的应用领域,本节介绍了成像,当然事实上不可能仅限于成像,经典的还如激光散斑的一些应用,干涉计量,还有傅里叶变换光谱学等等。最后总结一下,傅里叶光学我认为可以看做一个工具,对于任意的系统,它能给出一些数学思想与物理原理进行解释和分析,找出系统的扰动和响应的关系,或者说根据扰动和响应,来研究或者设计一个系统。

m0_53607446的博客 1672

K8S容器云平台查询容器TOP真实使用情况工具之Topic

K8S容器云平台查询容器TOP真实使用情况工具之Topic 1、说明 容器通过 cgroups和 namespace 实现了资源的轻量级隔离和限制,但容器中的/proc文件实际上是宿主机的,因此在执行 top命令查看容器运行信息时,部分指标显示不正确,例如启动时间、用户数、平均负载、cpu 使用率、内存使用率,那么如何在容器中查询top的使用情况呢?开源的二进制命令topic完美解决此问题。 ...

运维打怪晋级之路 1860

ROS Navigation global_planner框架解析

ROS Navigation global_planner框架解析主要讲一下我看源码总结的框架,如果大家跟着这个框架看源码的话可能会看的比较快。主要讲解global_planner关键配置参数含义及关键函数Astar,Dijkstra,QuadraticCalculator::calculatePotential,PotentialCalculator::calculatePotential,GridPath::getPath,GradientPath::getPath.

Jeff_Lee_的博客 4694

Unity工业数据可视化:基于ModbusTCP的实时数据通信实战

本文详细介绍了在Unity中实现工业数据可视化的核心方法,重点讲解了基于ModbusTCP协议与PLC等工业设备进行实时数据通信的实战流程。内容涵盖NModbus库的集成、Modbus Slave模拟器的使用、TCP连接的建立与多线程安全通信、数据读写与解析,以及如何将实时数据驱动3D场景,为构建工业数字孪生与监控系统提供完整解决方案。

ol7890123的博客 554

docker 命令详解(十二):top

docker top 命令详解。

youzhouliu的博客 1614

【AI测试干货】软件测试 - 全流程提示词完整体系

本篇教程是一套专为软件测试工程师打造的 AI 协作提示词体系。从测试计划制定、用例设计、自动化脚本开发、缺陷管理,到测试报告生成,每个环节都提供了结构化的提示词模板,帮助测试人员高效利用 AI 提升工作质量。

blues_C的博客 348

docker终极篇:再谈docker容器

容器容器其实是一种沙盒技术。顾名思义,沙盒就是能够像一个集装箱一样,把你的应用“装”起来的技术。这样,应用与应用之间,就因为有了边界而不至于相互干扰;而被装进集装箱的应用,也可以被方便地搬来搬去。对于进程来说,它的静态表现就是程序,平常都安安静静地待在磁盘上;而一旦运行起来,它就变成了计算机里的数据和状态的总和,这就是它的动态表现。而容器技术的核心功能,就是通过约束和修改进程的动态表现,从而为其创造出一个“边界”。基于Linux 内核的Cgroup,Namespace,以及Union FS。

weixin_41821642的博客 429

Unity的粒子系统使用shadergraph(内置管线)制作的一个顶点偏移shader,但是粒子模型移动时,顶点也会偏移?

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 1174

1篇1章4节:生成对抗网络GAN和图像生成领域的StyleGAN

AI图像生成技术的革命性突破:从GAN到StyleGAN 近年来,人工智能在图像生成领域取得显著进展,尤其是生成对抗网络(GAN)的发展推动了技术的飞跃。从早期的基础GAN到渐进式GAN(Progressive GAN),再到革命性的StyleGAN,AI生成图像的逼真度已接近人类创作水平。StyleGAN通过引入风格潜向量和自适应实例归一化,实现了对图像风格与内容的精细控制,广泛应用于人脸生成、艺术创作及影视行业。后续的StyleGAN2解决了“斑点”问题,StyleGAN3进一步优化纹理过渡,提升了图像

MD Code 218

Docker笔记-03 容器

简单介绍下Docker的重要概念-容器

2238

【MATLAB例程】三维下的IMM(交互式多模型),模型使用CV(匀速)和CA(匀加速),滤波使用EKF。附完整代码

CV模型:状态包含位置、速度和零加速度(9维状态),状态转移矩阵忽略加速度项CA模型:完整包含位置、速度和加速度(9维状态),状态转移矩阵包含二次项过程噪声矩阵Q分别根据两种模型的运动特性推导。

985工科博士毕业,专攻定位、导航和滤波等算法研究。从业10年,主要使用MATLAB 561

Java并发容器深度解析

容器线程安全机制是否有序读写特性内存消耗适用场景CAS+同步锁无序高并发读写中通用并发映射CAS无锁FIFO极高并发低无界生产者消费者CAS无锁双端极高并发低工作窃取模式CAS+跳表有序读多写少高有序并发映射CAS+跳表有序读多写少高有序并发集合写时复制有序读极多写极少高监听器列表/配置基于COWArrayList无序读极多写极少高小型不常变集合。

weixin_37944816的博客 963

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

深度解析Java并发容器【重点】

【重点】深度解析Java并发容器 概要结语   同学们,今天我们一起来深度解析Java当中的并发容器,通过本文的学习,你将了解到Java中有哪些常用的并发容器。 概要   前面我们解析了ArrayList集合以及HashMap的源码,其实很多同学都知道在多线程并发情况下,这两个类都不是线程安全的。所以在JDK1.5之前,没有现在的并发容器的概念,常常使用Collections提供的包装接口来将非同步容器转变为同步容器。其原理是通过加上synchronized关键字来修饰方法,我们可以来看下方法: List

ᶻᶻᶻ 枕星河的博客 1267

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Java全栈面试宝典:线程机制与Spring IOC容器深度解析

一、Java多线程高阶应用🔥 问题6:线程返回值获取三大方案方案对比与实现线程池最佳实践🔥 问题7:线程状态机全解析线程生命周期状态图关键状态说明🔥 问题8:sleep()与wait()的六大维度对比代码验证示例二、Spring IOC容器深度剖析🌟 IOC容器核心概念传统开发 vs IOC对比🌟 Spring IOC核心机制IOC容器架构图IOC核心功能清单三、高频面试题强化训练1. Spring IOC容器的启动过程?

2403_89107873的博客 1427

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

JAVA容器-重点总结与深度解析

JAVA容器-重点总结与深度解析 重点内容总结 问题思考 问题思考解析 posted @ 2017-03-16 20:43 邱勇Aries 阅读(...) 评论(...) 编辑 收藏 ...

码农皮邱 117

【Java】并发容器深度解析

Java并发容器深度解析:ConcurrentHashMap与CopyOnWriteArrayList ConcurrentHashMap在JDK7采用分段锁机制,通过16个Segment实现并发控制;JDK8+则优化为CAS+synchronized+红黑树结构,锁粒度细化到Node级别,查询性能提升至O(logn)。CopyOnWriteArrayList采用写时复制策略,读操作无锁,写操作复制新数组,适用于读多写少场景。两者都体现了Java并发容器的设计智慧:在并发安全与性能之间寻找最佳平衡点。

瘦到被风吹走的博客 791

Java 并发容器源码解析:ConcurrentSkipListSet 行级深度剖析

环节设计思想技巧/实现优点缺点数据结构跳表+Mapkey 唯一,value 恒定 TRUE有序、高效、并发安全value 存储冗余并发控制无锁/细粒度锁高吞吐,低延迟复杂实现,调试难度大查找/迭代有序视图+分片范围查询高效,分片灵活分片视图与原集合耦合克隆Unsafe 修改字段深度克隆,线程安全依赖内部 API,不可移植是 Java 并发容器中的有序集合之王,底层跳表设计,支持高并发、自动排序、范围查询,是大数据去重、排行榜、实时统计等场景的利器。

IT技术学习与工作笔记分享 1103

Java 并发容器:ConcurrentLinkedQueue 深度解析

ConcurrentLinkedQueue是Java并发包中的线程安全无界非阻塞队列,基于FIFO原则和CAS(Compare-And-Swap)操作实现。其核心特点包括:采用节点链接结构、HOPS设计模式减少CAS竞争、延迟更新头尾指针提高吞吐量。入队操作(offer)通过定位尾节点和CAS插入实现,出队操作(poll)通过CAS获取数据并更新head。该队列具有弱一致性,size()方法为O(n)时间复杂度且结果不精确。相比阻塞队列,在高并发场景下性能更优,适用于生产者-消费者模型等场景,但需注意避免内

油墨香^-^的博客 668

java基础:Java哈希容器对决:HashMap与Hashtable深度解析

在Java集合框架中,HashMap与Hashtable作为两种最常用的哈希表实现,看似功能相似却存在本质差异。本文将从线程安全性、性能特性、功能设计等维度深入对比,揭示两者在高并发场景下的适用边界,为容器选型选择提供实战指导。

weixin_43290370的博客 1007

java常用的容器类型有哪些,深度解析,值得收藏

第一部分 项目+自我介绍 首先上来简单做一下自我介绍? 然后让介绍简历里的项目,说下项目里的难点,技术架构。 平时开发过程中都遇到过哪些难题? 平时都这么和同事沟通? 第二部分 java基础方面 首先还是老生常谈的hashmap。hashmap的set和get的时间复杂度是多少?为什么是O(1), hashmap 在jdk1.8是线程安全的吗? 为什么是线程安全的?concureenthashmap了解吗?他是如何实现线程安全的? 说说java泛型,为什么称java泛型为伪泛

m0_57081368的博客 322

【Java每日一练-Day29】并发安全利器!并发容器深度解析+选型指南

Java并发容器种类繁多,今天重点拆解最常用的3类核心容器:ConcurrentHashMap(并发Map)、CopyOnWriteArrayList(并发List)、CopyOnWriteArraySet(并发Set),覆盖绝大多数多线程场景。在单线程环境下,HashMap、ArrayList等普通容器性能优异,但在多线程环境下,它们会暴露严重的线程安全问题,核心原因是“未做并发控制”——多个线程同时对容器进行读写操作时,会破坏容器的内部数据结构或导致数据不一致。

Xiong_Ji537的博客 609

K8S Java容器资源视图幻觉及过度并行的代价深度解析

12GB 场景任务轻(12GB)。虽然开了几十个线程(杀鸡用牛刀),但在系统总线和锁竞争还没达到瓶颈前,任务就结束了。结果:启动较快。36GB 场景任务重(36GB)。几十个线程同时涌入(万牛奔腾)。瞬间打满内存带宽,触发严重的锁竞争和上下文切换,所有线程都在“排队”等待资源。结果:启动巨慢,甚至比单线程处理还慢。

学亮编程手记 603
上一篇: 缓存重点知识总结以及分布式缓存框架redis和Memcached介绍
下一篇: [java] ArrayList和LinkedList实现原理及比较
topEngineerr
博客等级 码龄11年 627粉丝 157原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值