调试运行视频
python调试合集
java web 调试 视频合集
调试asp.net 项目相关合集
php 调试 视频合集
客服微信
客户问答
项目定制说明
作品发货方式
定制毕设需要的时间
成品可以修改吗
关于我们
翰文编程 CSDN博客
代做java毕业设计
信誉保证
购买流程
本站介绍
技术介绍
使用数据库
简单的基于地理图片的旅行路线还原
aScript 垃圾回收
Java中的不可变类
servlet 面试题
开发技术
ABO相关软件文件下载
基于Vue的生活废品回收系统的设计和实现
[免费获取]springboot 专升本志愿填报辅..
如何安装jdk
git 创建新项目,下载工程,合并和更新..
技术应用
ARM在adnroid开发应用
关于mysql
fusionCharts做bi展现基础技术
IoC容器类型
Ioc
移动手机软件的特点
J2ME介绍
手机软件现状
论文指导
广播电视大学论文应用指导要求
毕设题目参考二
毕设题目参考一
论文指导目录
开题报告指导
项目报告
论文开题报告格式
论文撰写的几大模块
当前位置:首页 > 查看
 

Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例

 来源:翰文编程 源码设计 定制服务  发布日期: 点击率:

第1部分 ArrayList介绍

ArrayList介绍

ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。
ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
ArrayList 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。稍后,我们会比较List的“快速随机访问”和“通过Iterator迭代器访问”的效率。
ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。
ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。

Vector不同,ArrayList中的操作不是线程安全的。所以,建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList

 

ArrayList的继承关系

复制代码
java.lang.Object
   ↳     java.util.AbstractCollection<E>          ↳     java.util.AbstractList<E>                ↳     java.util.ArrayList<E>public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}
复制代码

 

第2部分 ArrayList源码解析

为了更了解ArrayList的原理,下面对ArrayList源码代码作出分析。ArrayList是通过数组实现的,源码比较容易理解。 

  1 package java.util;  2   3 public class ArrayList<E> extends AbstractList<E>  4         implements List<E>, RandomAccess, Cloneable, java.io.Serializable  5 {  6     // 序列版本号   7     private static final long serialVersionUID = 8683452581122892189L;  8   9     // 保存ArrayList中数据的数组  10     private transient Object[] elementData; 11  12     // ArrayList中实际数据的数量  13     private int size; 14  15     // ArrayList带容量大小的构造函数。  16     public ArrayList(int initialCapacity) { 17         super(); 18         if (initialCapacity < 0) 19             throw new IllegalArgumentException("Illegal Capacity: "+ 20                                                initialCapacity); 21         // 新建一个数组  22         this.elementData = new Object[initialCapacity]; 23     } 24  25     // ArrayList构造函数。默认容量是10。  26     public ArrayList() { 27         this(10); 28     } 29  30     // 创建一个包含collection的ArrayList  31     public ArrayList(Collection<? extends E> c) { 32         elementData = c.toArray(); 33         size = elementData.length; 34         // c.toArray might (incorrectly) not return Object[] (see 6260652)  35         if (elementData.getClass() != Object[].class) 36             elementData = Arrays.copyOf(elementData, size, Object[].class); 37     } 38  39  40     // 将当前容量值设为 =实际元素个数  41     public void trimToSize() { 42         modCount++; 43         int oldCapacity = elementData.length; 44         if (size < oldCapacity) { 45             elementData = Arrays.copyOf(elementData, size); 46         } 47     } 48  49  50     // 确定ArrarList的容量。 51     // 若ArrayList的容量不足以容纳当前的全部元素,设置 新的容量=“(原始容量x3)/2 + 1”  52     public void ensureCapacity(int minCapacity) { 53         // 将“修改统计数”+1  54         modCount++; 55         int oldCapacity = elementData.length; 56         // 若当前容量不足以容纳当前的元素个数,设置 新的容量=“(原始容量x3)/2 + 1”  57         if (minCapacity > oldCapacity) { 58             Object oldData[] = elementData; 59             int newCapacity = (oldCapacity * 3)/2 + 1; 60             if (newCapacity < minCapacity) 61                 newCapacity = minCapacity; 62             elementData = Arrays.copyOf(elementData, newCapacity); 63         } 64     } 65  66     // 添加元素e  67     public boolean add(E e) { 68         // 确定ArrayList的容量大小  69         ensureCapacity(size + 1);  // Increments modCount!! 70         // 添加e到ArrayList中  71         elementData[size++] = e; 72         return true; 73     } 74  75     // 返回ArrayList的实际大小  76     public int size() { 77         return size; 78     } 79  80     // 返回ArrayList是否包含Object(o)  81     public boolean contains(Object o) { 82         return indexOf(o) >= 0; 83     } 84  85     // 返回ArrayList是否为空  86     public boolean isEmpty() { 87         return size == 0; 88     } 89  90     // 正向查找,返回元素的索引值  91     public int indexOf(Object o) { 92         if (o == null) { 93             for (int i = 0; i < size; i++) 94             if (elementData[i]==null) 95                 return i; 96             } else { 97                 for (int i = 0; i < size; i++) 98                 if (o.equals(elementData[i])) 99                     return i;100             }101             return -1;102         }103 104         // 反向查找,返回元素的索引值 105         public int lastIndexOf(Object o) {106         if (o == null) {107             for (int i = size-1; i >= 0; i--)108             if (elementData[i]==null)109                 return i;110         } else {111             for (int i = size-1; i >= 0; i--)112             if (o.equals(elementData[i]))113                 return i;114         }115         return -1;116     }117 118     // 反向查找(从数组末尾向开始查找),返回元素(o)的索引值 119     public int lastIndexOf(Object o) {120         if (o == null) {121             for (int i = size-1; i >= 0; i--)122             if (elementData[i]==null)123                 return i;124         } else {125             for (int i = size-1; i >= 0; i--)126             if (o.equals(elementData[i]))127                 return i;128         }129         return -1;130     }131  132 133     // 返回ArrayList的Object数组 134     public Object[] toArray() {135         return Arrays.copyOf(elementData, size);136     }137 138     // 返回ArrayList的模板数组。所谓模板数组,即可以将T设为任意的数据类型 139     public <T> T[] toArray(T[] a) {140         // 若数组a的大小 < ArrayList的元素个数;141         // 则新建一个T[]数组,数组大小是“ArrayList的元素个数”,并将“ArrayList”全部拷贝到新数组中 142         if (a.length < size)143             return (T[]) Arrays.copyOf(elementData, size, a.getClass());144 145         // 若数组a的大小 >= ArrayList的元素个数;146         // 则将ArrayList的全部元素都拷贝到数组a中。 147         System.arraycopy(elementData, 0, a, 0, size);148         if (a.length > size)149             a[size] = null;150         return a;151     }152 153     // 获取index位置的元素值 154     public E get(int index) {155         RangeCheck(index);156 157         return (E) elementData[index];158     }159 160     // 设置index位置的值为element 161     public E set(int index, E element) {162         RangeCheck(index);163 164         E oldValue = (E) elementData[index];165         elementData[index] = element;166         return oldValue;167     }168 169     // 将e添加到ArrayList中 170     public boolean add(E e) {171         ensureCapacity(size + 1);  // Increments modCount!! 172         elementData[size++] = e;173         return true;174     }175 176     // 将e添加到ArrayList的指定位置 177     public void add(int index, E element) {178         if (index > size || index < 0)179             throw new IndexOutOfBoundsException(180             "Index: "+index+", Size: "+size);181 182         ensureCapacity(size+1);  // Increments modCount!! 183         System.arraycopy(elementData, index, elementData, index + 1,184              size - index);185         elementData[index] = element;186         size++;187     }188 189     // 删除ArrayList指定位置的元素 190     public E remove(int index) {191         RangeCheck(index);192 193         modCount++;194         E oldValue = (E) elementData[index];195 196         int numMoved = size - index - 1;197         if (numMoved > 0)198             System.arraycopy(elementData, index+1, elementData, index,199                  numMoved);200         elementData[--size] = null; // Let gc do its work 201 202         return oldValue;203     }204 205     // 删除ArrayList的指定元素 206     public boolean remove(Object o) {207         if (o == null) {208                 for (int index = 0; index < size; index++)209             if (elementData[index] == null) {210                 fastRemove(index);211                 return true;212             }213         } else {214             for (int index = 0; index < size; index++)215             if (o.equals(elementData[index])) {216                 fastRemove(index);217                 return true;218             }219         }220         return false;221     }222 223 224     // 快速删除第index个元素 225     private void fastRemove(int index) {226         modCount++;227         int numMoved = size - index - 1;228         // 从"index+1"开始,用后面的元素替换前面的元素。 229         if (numMoved > 0)230             System.arraycopy(elementData, index+1, elementData, index,231                              numMoved);232         // 将最后一个元素设为null 233         elementData[--size] = null; // Let gc do its work 234     }235 236     // 删除元素 237     public boolean remove(Object o) {238         if (o == null) {239             for (int index = 0; index < size; index++)240             if (elementData[index] == null) {241                 fastRemove(index);242             return true;243             }244         } else {245             // 便利ArrayList,找到“元素o”,则删除,并返回true。 246             for (int index = 0; index < size; index++)247             if (o.equals(elementData[index])) {248                 fastRemove(index);249             return true;250             }251         }252         return false;253     }254 255     // 清空ArrayList,将全部的元素设为null 256     public void clear() {257         modCount++;258 259         for (int i = 0; i < size; i++)260             elementData[i] = null;261 262         size = 0;263     }264 265     // 将集合c追加到ArrayList中 266     public boolean addAll(Collection<? extends E> c) {267         Object[] a = c.toArray();268         int numNew = a.length;269         ensureCapacity(size + numNew);  // Increments modCount 270         System.arraycopy(a, 0, elementData, size, numNew);271         size += numNew;272         return numNew != 0;273     }274 275     // 从index位置开始,将集合c添加到ArrayList 276     public boolean addAll(int index, Collection<? extends E> c) {277         if (index > size || index < 0)278             throw new IndexOutOfBoundsException(279             "Index: " + index + ", Size: " + size);280 281         Object[] a = c.toArray();282         int numNew = a.length;283         ensureCapacity(size + numNew);  // Increments modCount 284 285         int numMoved = size - index;286         if (numMoved > 0)287             System.arraycopy(elementData, index, elementData, index + numNew,288                  numMoved);289 290         System.arraycopy(a, 0, elementData, index, numNew);291         size += numNew;292         return numNew != 0;293     }294 295     // 删除fromIndex到toIndex之间的全部元素。 296     protected void removeRange(int fromIndex, int toIndex) {297     modCount++;298     int numMoved = size - toIndex;299         System.arraycopy(elementData, toIndex, elementData, fromIndex,300                          numMoved);301 302     // Let gc do its work 303     int newSize = size - (toIndex-fromIndex);304     while (size != newSize)305         elementData[--size] = null;306     }307 308     private void RangeCheck(int index) {309     if (index >= size)310         throw new IndexOutOfBoundsException(311         "Index: "+index+", Size: "+size);312     }313 314 315     // 克隆函数 316     public Object clone() {317         try {318             ArrayList<E> v = (ArrayList<E>) super.clone();319             // 将当前ArrayList的全部元素拷贝到v中 320             v.elementData = Arrays.copyOf(elementData, size);321             v.modCount = 0;322             return v;323         } catch (CloneNotSupportedException e) {324             // this shouldn't happen, since we are Cloneable 325             throw new InternalError();326         }327     }328 329 330     // java.io.Serializable的写入函数331     // 将ArrayList的“容量,所有的元素值”都写入到输出流中 332     private void writeObject(java.io.ObjectOutputStream s)333         throws java.io.IOException{334     // Write out element count, and any hidden stuff 335     int expectedModCount = modCount;336     s.defaultWriteObject();337 338         // 写入“数组的容量” 339         s.writeInt(elementData.length);340 341     // 写入“数组的每一个元素” 342     for (int i=0; i<size; i++)343             s.writeObject(elementData[i]);344 345     if (modCount != expectedModCount) {346             throw new ConcurrentModificationException();347         }348 349     }350 351 352     // java.io.Serializable的读取函数:根据写入方式读出353     // 先将ArrayList的“容量”读出,然后将“所有的元素值”读出 354     private void readObject(java.io.ObjectInputStream s)355         throws java.io.IOException, ClassNotFoundException {356         // Read in size, and any hidden stuff 357         s.defaultReadObject();358 359         // 从输入流中读取ArrayList的“容量” 360         int arrayLength = s.readInt();361         Object[] a = elementData = new Object[arrayLength];362 363         // 从输入流中将“所有的元素值”读出 364         for (int i=0; i<size; i++)365             a[i] = s.readObject();366     }367 }
View Code

总结
(01) ArrayList 实际上是通过一个数组去保存数据的。当我们构造ArrayList时;若使用默认构造函数,则ArrayList默认容量大小是10
(02) 当ArrayList容量不足以容纳全部元素时,ArrayList会重新设置容量:新的容量=“(原始容量x3)/2 + 1”
(03) ArrayList的克隆函数,即是将全部元素克隆到一个数组中。
(04) ArrayList实现java.io.Serializable的方式。当写入到输出流时,先写入“容量”,再依次写入“每一个元素”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。

请加微信,客服二维码请咨询购买,同时本程序源码配有系统运行视频 请联系客服索要视频文件


网址:毕设在线毕业设计网 http://www.bisheonline.net

服务范围:定制各类计算机程序设计,vue,jsp ,java 各类框架各类,开发工具 eclipse myeclipse idea vs 等,wap android ssm springboot asp.net php python (爬取,django,flask) vue node.js react ,winform uniapp小程序 等 E-mail:251836457@qq.com

友情链接: 翰文编程 CSDN博客   翰文编程 B站空间   计算机联盟  

翰文编程 源码设计 定制服务 版权所有

辽ICP备12012783


Copyright(C) 毕设在线(bisheonline.net) All Rights Reserved.


客服Q Q:251836457 翰文编程 源码设计 定制服务客服为你服务
360安全网址导航
Baidu