当前课程知识点:JAVA程序设计进阶 >  第七章 深入集合Collection >  7.1 集合框架与ArrayList >  Video

返回《JAVA程序设计进阶》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《JAVA程序设计进阶》慕课在线视频列表

Video课程教案、知识点、字幕

这一节我们来介绍一下

集合框架与arraylist

我们首先看一下这张图

在这张图上列出了

我们常见的一些集合框架的类

最上面的话

是我们的collection接口

那它有两个子接口 list和set

那再往下我们还可以看到

这些list有一些类来去实现这个接口

比如说AbstractList

那AbstractList往下

还有Vector Stack

甚至还有ArrayList等等等等

但对于set这个接口的话

底下也实现了一些类

比如说最下面的HashSet

或者TreeSet等等

但是这张图的右半部分

是我们另外一个接口叫Map

那个这个Map大家可以看到

它也延伸有很多很多的这些类

比如说HashMap LinkedHashMap

还有Hashtable等等

那这些类的话

都是我们在集合框架当中

比较常见的类

那这儿也列出了一些

常用集合类的名字

比如说在list

我们就会有ArrayList和LinkedList

这两个类

那在Map这个接口

我们就会有HashMap Hashtable

还有TreeMap LinkedHashMap等

这样四个常用的类

那对于Set

集合这个接口

我们常用的类包括HashSet

TreeSet和LinkedHashSet等等这些

都是我们在进行Java编程时候

所经常使用到的Java的数据结构类

那我们首先来看一个

最常见的类ArrayList

那ArrayList它是List接口

所实现的可变的数组

那在这里面实现了

所有可选列表的操作

允许包括null在内的所有的元素

当然ArrayList这个类

它是属于非线程安全

什么意思

就是说ArrayList在我们进行

多性能操作的时候

你们编程序的时候

一定要去主动加上(02:46英文)

这样的控制

才能保证多个线程

同时对ArrayList进行访问的时候

数据的安全性

那在ArrayList它的实现的内部结构

使用的是数组

一会儿我们可能会具体介绍

它的实现过程

那ArrayList它的特点是

它比较适合于去查找

当我们需要对ArrayList

进行增加或者删除的时候

它的这个性能就会受到影响

我们来看一下ArrayList

它到底是怎么实现的

那我们看一下第三行

我们这个类public E set

int index E element

那实际上这是一个方法

那这个方法就是说

我们想把这个列表上的

某一个元素的值

进行变更或者叫进行设置

那我们看这个方法里面的第一行

Range Check index

那这个方法是要检查说

你的index是否合法

也就是说我们要对某一个下标的

这个ArrayList的元素进行修改的时候

首先你看这个下标

也就是index是否越界

再往下一行E oldValue等于

elementData index

那就直接取出在原有的这个下标index

所对应的元素的值

把它保存在oldValue这个对象当中

然后elementData index等于element

那这个就是把我们下标为index

这个元素把它的值

设置为要新的值

就是这个element

紧接着下一行return old Value

那就是把旧的这个元素值返回

那这个方法的话

就是一个在ArrayList中

实现替换元素的这么一个方法

那再往下的话是增加元素的方法

那增加元素它主要是把它添加到

我们整个列表的尾部

我们看一下这一段代码

public boolean add E e

这个方法中第一行

ensureCapacity size+1

确保说我还有一个额外的这个容量

因为你要增加元素

我们要往这个列表的末尾增加

那我们就要看这个

是不是已经到达了整个列表的

最后的这个位置

再下一行elementData size++ =e

那就是说把这个最后的这个位置的

这个元素值设置成为e

也就是我们想增加的这个值

最后return true也就是表示增加成功了

那这两个方法就是我们ArrayList

当中的分别设定某个元素值的方法

以及在尾部增加某个元素的方法

那我们再往下看

当我们想往ArrayList这个列表当中

去增加或者叫插入某一个元素的时候

那你肯定要指定说

我要在哪个位置插入什么样的一个元素

我们看一下这段代码

public void add

int index E element

那这个方法就是add

只不过说它不是add到

这个列表的尾部

它是增加到某一个这个下标下面

就是由index来去指出这个位置

在这里插入一个元素

那插入的元素值就是element

那我们看看这个下一行代码是什么

if index大于size 或者index小于0

也就是说我们这个add

这个index参数

如果你指定的这个下标的位置

是已经超出了整个列表的范围

或者是小于0

那就说明你整个就是

这个相当于数组下标越界了

所以我们可以看到再下一行代码

就throw newindexOutOfBoundsException

然后index+index再加上size

那实际上在这个时候

就是生成了一个数组下标越界的异常

并把它抛出去

那假设都没有这个下标越界的话

那说明我们是可以去

这个往里添加的元素

再下一行代码ensureCapacity size+1

也是要确保说

我要往里这个插入元素的时候

我的整个这个列表的空间

还是能够容纳的

拿再往下就是system.arraycopy

elementData index

elementData index+1

然后最后size-index

那其实这个arraycopy的方法

它的作用就是相当于

把我们列表当中的若干元素的值

进行拷贝

那为什么要拷贝呢

因为我们当前要实现的这个add方法

实际上是说在列表当中的

某个位置去插入这个元素

我要插入元素的时候

必定是把从当前要插入这个位置

之后的这些元素

全都集体往后挪一位

然后紧接着再把要新增的元素

放到这个下标这个位置上面

所以这个system.arraycopy

就是把这个位置后面的这个元素

整体移动的过程

那再下一行代码就是collectionData

index等于element

那就是说把我们这个当前下标

所指定的元素的值

设定为我要插入的值

最后一行代码是size++

就是增加我们的整个空间

增加一个值

那我们可以看到在我们左下角

已经标明了一个列表的初始状态

这个列表有五个元素的空间

然后分别从第一到第四个是abcd

然后现在我们想在c

也就是下标为2的这个地方

想去插入这个

一个新的这个元素

那它的整个过程是怎么样的呢

这个很显然

我们要先把这个

由这个index这个指针指向的这个位置

之后的就是这些元素都往后挪一格

大家可以看到我们把cd

整个往后挪了一个位置

也就是说整体拷贝挪了一个位置

紧接着最后我们要把我们想插入的元素

插进来

那假设现在我们想插入的是e

所以我们插进来的这个列表的

最后的结果就是abecd

那其实这个过程

打一个比方就像

相当于大家去食堂打饭的时候

可能会碰到有人上来插队

或者叫加塞的

那其实这个过程

就是和那个过程是类似的

如果有一个人插到队伍中间

那从他插的那个队伍开始

那个后面所有人

都要往后挪一格

那这个时候我们这个add方法

其实就是类似的道理

当然大家也可以看出来

这里面有一个特点就是说

往后挪一格的这个代价还是蛮大的

因为你要把这个从插队开始

后面位置的所有的这些元素

都要往后挪一位

那在我们这里面

就是要逐一进行拷贝

所以它在列表

在进行插入操作的时候

它的这个性能确实不是很好

那我们再看下一个方法

也就是删除方法

就是从列表当中去删除

指定位置上的元素

那这个方法叫public E remove

int index

也就是说我们要删除某个元素的时候

你只需要指定是删除哪个位置上

也就是哪个下标上的元素就可以了

然后先来说RangeCheck index

先来检查一下这个给定的index

是不是超出了我们这个列表的

这个长度

或者是它就根本小于0

那如果都符合要求

那我们再往下看

那这个modCount++

实际上是说这个修改的次数加一的意思

然后紧接着这个E oldValue

等于elementData index

那这一行代码什么意思呢

也就是说先把我们当前

要删除的这个元素

它的值给保留下来

保存到oldValue这个对象当中

好 紧接着int numMoved

等于size-index-1

那其实我们当我们往列表当中

去删除某一个元素的时候

这个时候从这个元素之后的其他元素

都要往前去补空

那到底要多少个元素

要往前去补空呢

就由这个numMoved来去计算出来

那numMoved等于size-index-1

然后这时候再往下

我们看那个代码if numMoved大于0

就是说它要移动的这个数量的话

原数量是大于0的

那就进行这个拷贝移动

那怎么拷贝移动

还是调用system这个类的arraycopy方法

然后从哪些原来的数据去拷贝呢

从elementData这个列表的

它从下标index+1开始

那到底想拷贝到哪儿呢

拷贝到elementData这个列表

然后从它的这个index这个下标开始

然后要总共拷贝多少个呢

拷贝numMoved个

其实说白了也就是把这个元素

整体往前挪了一位

然后最后一步

elementData--size等于null

也就是说我们最后的一个元素

它是往前拷贝

但是最后这个元素它所在的这个位置

它的值应该把它置成空

所以就把它设置成null

然后最后我们return oldValue

也就是把我们这个旧有的

被删除的值返回去

那下面我们用一个小的动画

来去展示这个删除的过程

那我们这里有一个列表

它有四个元素

分别是abcd

那现在我们想把第二个元素

也就是下标为1的这个元素进行删除

也就是要把b元素删除

那b元素删除第一步做什么事情呢

就是把后面的c和d整体往前拷贝

覆盖掉原来b的这个位置

那就变成了acdd

大家看到最后这个元素它还是d

因为我们这个是把原来的cd

往前挪了一位

那最后这个位置还是d的话

就显得有点不合理了

所以我们还增加了一步

把这个d修改成为空

也就是把它这个给空出来

所以这么一个删除过程

再给大家举这个例子

就是像刚才我们说去食堂

这个排队的时候有人插队了

但是这个时候大家有了意见

要求插队的人赶紧从队伍中离开

那一旦插队的人

从队伍离开的话

从后面开始的人

就可以一次往前递补

移动一个位置

当然这个递补移动的位置

在我们用列表来实现的时候

你是要整体拷贝了

所以说我们的列表对于删除这样的操作

它确实在性能上表现的还不够好

那再下面这个方法是

就是去扩充我们整个这个数组

也就是我们这个列表的容量的

那它public void ensureCapacity

然后int min Capacity

那这个参数就是说

我希望确认一下说

我这个列表的长度

它不小于我这个长度

好 我们再往下看一下

modCount++这是修改次数加1

int old Capacity

等于elementData.length

也就是说旧有的这个容量大小

就是我们整个列表的它的长度

再往下if minCapacity

大于oldCapacity

也就是说我们要想指定的最小的

这个容量minCapacity

比现有的容量还要大的话

这就说明说这个列表

不能满足我的使用需求

这个时候就需要对列表的长度

进行扩充

怎么扩充呢

基本原则就是扩到1.5倍

我们看一下int newCapacity

等于oldCapacity乘以3除以2再加1

实际上它是乘以1.5倍再加1

然后这时候接着再往下判断

if newCapacity小于minCapacity

也就是说我们经过1.5倍

扩充以后的这个列表的长度

还比那个

在这个方法的参数里面指定的

minCapacity还小的话

那这时候我们只好把这个newCapacity

把它设置为minCapacity

也就是说把我们新变化后的

这个列表的容量它的值

就设定为这个参数里面

定义这个minCapacity的值

那设好这些这个列表的容量

或者叫长度以后

那它原来我们的列表当中

是不是也保存了一些数据

当然极有可能有

那这个时候怎么办

大家再看一下最后这一行

elementData等于arrays.copy of

elementData newCapacity

其实就是把这个原有的这些元素

再重新进行一遍这个拷贝

所以我们这个ensureCapacity

这个方法它是按照1.5倍的方式

进行扩充

来扩充我们的这个数组列表

那由于在这个扩充过程中

涉及到这个数组元素的拷贝

那这个速度的话

肯定是会相应的会减慢的

那这一节的内容我们就介绍到这里

JAVA程序设计进阶课程列表:

第一章 线程(上)

-1.0 导学

--Video

-1.1 线程的基本概念

--Video

-1.1 线程的基本概念--作业

-1.2 通过Thread类创建线程

--Video

-1.2 通过Thread类创建线程--作业

-1.3 线程的休眠

--Video

-1.3 线程的休眠--作业

-1.4 Thread类详解

--Video

-1.5 通过Runnable接口创建线程

--Video

-1.5 通过Runnable接口创建线程--作业

-1.6 线程内部的数据共享

--Video

第二章 线程(中)

-2.0 导学

--Video

-2.1 线程同步的思路

--Video

-2.2 线程同步的实现方式—Synchronization

--Video

-2.3 线程的等待与唤醒

--Video

-2.4 后台进程

--Video

-2.5 线程的生命周期与死锁

--Video

-2.6 线程的调度

--Video

第三章 线程(下)

-3.0 导学

--Video

-3.1 线程安全与线程兼容与对立

--Video

-3.2 线程的安全实现-互斥同步

--Video

-3.3 线程的安全实现-非阻塞同步

--Video

-3.4 线程的安全实现-无同步方案

--Video

-3.5 锁优化

--Video

第四章 网络编程(上)

-4.0 导学

--Video

-4.1 URL对象

--Video

-4.2 URLConnection对象

--Video

-4.3 Get请求与Post请求

--Video

-4.4 Socket通信原理

--Video

-4.5 Socket通信实现

--Video

第五章 网络编程(下)

-5.0 导学

--Video

-5.1 Socket 多客户端通信实现

--Video

-5.2 数据报通信

--Video

-5.3 使用数据报进行广播通信

--Video

-5.4 网络聊天程序

--Video

第六章 Java虚拟机

-6.0 导学

--Video

-6.1 Java虚拟机概念

--Video

-6.2 Java虚拟机内存划分

--Video

-6.3 Java虚拟机类加载机制

--Video

-6.4 判断对象是否存活算法及对象引用

--Video

-6.5 分代垃圾回收

--Video

-6.6 典型的垃圾收集算法

--Video

-6.7典型的垃圾收集器

--Video

第七章 深入集合Collection

-7.0 导学

--Video

-7.1 集合框架与ArrayList

--Video

-7.2 LinkedList

--Video

-7.3 HashMap与HashTable

--Video

-7.4 TreeMap与LinkedHashMap

--Video

-7.5 HashSet

--Video

第八章 反射与代理机制

-8.0 导学

--Video

-8.1 Java反射机制

--Video

-8.2 Java静态代理

--Video

-8.3 Java动态代理

--Video

-8.4 Java 反射扩展-jvm加载类原理

--Video

-8.5 Java进阶课程总结

--Video

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。