IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 你真的懂Java的ArrayList吗? -> 正文阅读

[Java知识库]你真的懂Java的ArrayList吗?

1. 为什么需要ArrayList?

图1图2
在这里插入图片描述在这里插入图片描述

记得在刚刚学习Java的时候,我们首先是学习了数组,这是我们学到的第一个可以存储多个对象的实例或者基本类型的具体值,数组存储的特点如下:

  1. 只能存储同种类型的数据。
  2. 在定义数组时,必须指定该数组的大小,并且在不改变数组的前提下,不可修改其长度。

以上特性就会导致很多弊端。比如:我们往往不希望数组只能存储一种数据,而是希望存储我们想要存储的数据,最好是在想要存储的时候根据数据的类型指定存储的类型。其次,我们也不想一开始就指定好数据的长度,而是希望这个数组的容量可以随着我的数据的多少的改变而改变。

基于以上的弊端,Java中出现了集合。这是一种新的容器可以用来存储数据,而集合的存储方式有多种,常见的有链式存储(LinkedList)和顺序存储(ArrayList)。

链式存储底层是用一个个节点(Node)链接而成的,每个节点都存储着一个对象值和下一个节点的位置(或上一个节点的位置)。

顺序存储底层是用一个数组存储数据的,对于数组的弊端,顺序存储集合底层使用了ensureCapacity这个方法不断扩容,ensureCapacity这个单词字面翻译是 保证能力。顾名思义,由于底层是一个数组,当我们存入一个对象时,我们需要保证数组是有空余位置的,因此在添加元素的时候,Java源码会先经过这个方法进行判断底层数组是否满了,若满了则会扩容数组(上面提到数组是不能直接扩容的,这里实际上是重新创建了一个更大空间的数组并把元素“搬运”过去)。这样就解决了数组的一个弊端。而对于另一个弊端,Java则是巧妙的运用了泛型。泛型的内容非常繁多,这里结合实例希望大家可以更好的理解。

想象一下现在有一个需求,需要你实现一个的多值加法,但传入的参数的类型是不确定的,可以有Integer,String,Double等等。这时候如果你用的是数组作为参数,那么那你肯定会想,最粗糙的方法是分别写多个加法方法,对应不同的类型,但很明显,代码可读性极差,那如果使用Object数组,然后再根据数据类型,转换为对应的类型再计算?这样也存在弊端!你根本不知道需要转换为什么类型才合适。因此,针对这种情况,使用泛型集合是最合适的,我们只需要在传入参数的时候使用泛型类型,而因为不同类型计算的过程是一致的,因此结果并没有差别,也不会导致报错。

2. ArrayList底层是如何实现的?

简单介绍了ArrayList的用途以及和数组的区别,那么根据上面的讲解,你应该大致了解它的实现原理了吧!

先不看源码,如果你有一些数据结构与算法的基础的话,你应该可以马上得出下面结论:先在ArrayList类定义一个数组,接着定义一个添加,一个删除,一个查询,一个修改方法。实际上是对数组的操作,那么,删除和添加可能需要移动大量的元素,这些都是在源码中实现,但对应到效率也会很低,其次还需要一个扩容数组的方法。

如果你能想到上面这些,恭喜你,你已经掌握的很不错。事实上,ArrayList的源码确实包含以上方法,只不过还需要加上迭代器以及构造方法等。迭代器的出现是为了适应增强for语句(后面会细说),构造方法是为了初始化集合。

3. 结合源码分析主要成员变量

ArrayList继承AbstractList这个抽象类和List接口
在这里插入图片描述List接口继承Collection接口(实际上集合还有map集合等)
在这里插入图片描述
而Collection则是继承了Iterable(可迭代的),Collection中包含了集合中通用的方法,包括增删改查,只不过都未实现。而Iterable则是只有一个forEach方法,提供迭代。
在这里插入图片描述
在这里插入图片描述
接着我们回到ArrayList类,这是底层维护的数组,实际上对象存储的地方,
记录集合的长度
在这里插入图片描述
返回集合的长度
在这里插入图片描述
判断集合是否为空
在这里插入图片描述
根据索引获取元素
在这里插入图片描述
添加元素
在这里插入图片描述
添加元素到指定位置
在这里插入图片描述
删除元素
在这里插入图片描述
内部类的next方法实现迭代功能(我们平时使用增强for语句的判断条件就是根据判断是否有next值来实现的)
在这里插入图片描述

4. 个人的一点总结

Java的设计者很巧妙的设计了Java中的每个功能,很多时候,我们会觉得说我手动实现简单的集合不需要这么复杂的代码呀?甚至有些功能都不需要单独作为一个方法。但这就是Java的魅力啊!

以前刚学代码的我们,把代码全都丢到main方法里面,我们会觉得提取出来是多么复杂,但当我们知道功能是有区别的,我们才知道这样子做的用处。
曾经有个老师这么对我说,他说你知道为什么我们要费尽心思去设计各种类之间的关系,接口,抽象类,泛型等等吗?那时候的我一脸茫然,他对我说,打个比方,你见过卖水果的店里还卖手机的吗?我听完后恍然大悟,对于一个小城镇,确实可能存在一个小店卖着各种杂七杂八的东西,但一个千万人口的大城市,是做不到的,这是格局啊!各种功能,各种设施都应该井井有条,关系明确。面向对象也好,设计模式也好,一切的功能都是为了大型程序做准备,这也是为什么Java一直可以大型应用的后端程序语言之一。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-10 13:17:12  更:2021-08-10 13:17:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 8:23:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码