ArrayList的add方法实现
ArrayList的底层是由数组实现,所以所有的操作都是围绕数组展开,要想理解add方法,就得先了解数组的增加,所以我们先实现一个数组的add,数组的添加可以从尾部增加或者其他位置插入,
如果在数组的尾部插入,只需要拿到数组的长度,直接在该索引处赋予元素值,下面自己手动简单实现一个在数组任意位置实现数组元素添加:
public class MyArray {
public static void main(String[] args) {
/*创建一个数组*/
Object[] objectArray = new Object[10];
for (int i = 0; i < 10; i++) {
objectArray[i] = i;
}
System.out.println("原数组");
for (int i = 0; i < objectArray.length; i++) {
System.out.print(objectArray[i] + ",");
}
System.out.println();
System.out.println("插入后的数组");
Object[] newArray;
try {
newArray = MyArray.add(objectArray, 3, "hello");
for (int i = 0; i < newArray.length; i++) {
System.out.print(newArray[i] + ",");
}
} catch (Exception e) {
e.printStackTrace();
}
}
/*在一个数组的任意位置插入一个元素*/
public static Object[] add(Object[] objectArray, int index, Object object) throws Exception {
if(index < 0 || index - objectArray.length > 0) {
throw new Exception("数组索引无效" + index);
}
Object[] newObjectArray = new Object[objectArray.length];
/*首先将插入位置之前的所有元素拷贝到一个新的数组中*/
for (int i = 0; i < index; i++) {
newObjectArray[i] = objectArray[i];
}
/*然后将剩下的元素拷贝到插入位置加1后面的位置*/
for (int i = index + 1; i < objectArray.length; i++) {
if(!"".equals(objectArray[i])) {
newObjectArray[i] = objectArray[i - 1];
}
}
/*将新增的元素放到插入的位置*/
newObjectArray[index] = object;
return newObjectArray;
}
}
(1) add方法
如果想在数组的任意位置插入元素,我们需要建立一个新的数组,将插入位置前面的元素拷贝到新数组中,将插入位置后面的元素的下标都后移一位,将插入位置腾出,
将需要插入的元素放入该位置,比起上面的demo,ArrayList的实现稍微复杂,在上述的过程中加入了扩容机制,也不会上面一样将一个数组整个复制到另一个新数组中,
而是原来数组插入位置后面的元素按顺序复制到原数组插入位置+1的位置,下面为ArrayList的add方法源码:
public void add(int index, E element) {
/*判断插入的索引是否符合ArrayList范围,在0 和 size之间,size是ArrayList实际元素个数,不包括底层数组的null元素*/
rangeCheckForAdd(index);
/*扩容机制:判断添加是否需要进行扩容*/
ensureCapacityInternal(size + 1); // Increments modCount!!
/*将旧数组拷贝到一个新数组中,参数:被复制的原数组, 被复制数组的第几个元素开始复制, 复制的目标数组, 从目标数组index + 1位置开始粘贴, 复制的元素个数,*/
System.arraycopy(elementData, index, elementData, index + 1, size - index);
/*将新元素赋予该下标*/
elementData[index] = element;
/*元素个数+1*/
size++;
}
(2) addAll()方法
ArrayList的addAll()方法的实现和add()方法实现思路一致,只不过需要移动的元素更多,由于数组结构的特性,导致这样的操作对于数据大的ArrayList的插入操作,
会严重影响代码执行的效率,所以开发中我们应该尽量避免出现对数据元素多的ArrayList频繁add。
public boolean addAll(Collection<? extends E> c) {
/*转为对象数组*/
Object[] a = c.toArray();
int numNew = a.length;
/*扩容机制:判断是否需要扩容*/
ensureCapacityInternal(size + numNew); // Increments modCount
/*拷贝数组,参数:被复制的数组,被复制数组的第几个元素开始复制,复制到目标数组,目标数组粘贴的位置, 复制的个数*/
System.arraycopy(a, 0, elementData, size, numNew);
/*数组长度+numNew*/
size += numNew;
return numNew != 0;
}
public boolean addAll(int index, Collection<? extends E> c) {
/*判断索引是否有效*/
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
/*扩容机制:判断是否需要扩容*/
ensureCapacityInternal(size + numNew); // Increments modCount
/*需要移动的元素个数*/
int numMoved = size - index;
/*如果插入位置不在尾部,则移动原数组index以后的元素,未插入c腾出空间,如果在尾部,与addAll(Collection<? extends E> c)方法相同*/
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew, numMoved);
/*将需要插入的数组插入到腾出空间中*/
System.arraycopy(a, 0, elementData, index, numNew);
/*长度+numNew*/
size += numNew;
return numNew != 0;
}
ArrayList的add方法实现的更多相关文章
- 关于ArrayList add()方法 中的引用问题
ArrayList的add方法每次添加一个对象时,添加 的是一个对象的引用,比如进行循环操作10次 lists.add(a) 每次 a会改变 ,这时候你会发现你在lists里添加了10个相同的对象a ...
- ArrayList的add(E e)方法与扩容
ArrayList是Java开发中经常用到的集合类,它是List接口的实现类,具有很高的查询性能,但不是线程安全的.本文主要讲述了ArrayList的add(E e)方法及该方法中涉及到的容量扩容技术 ...
- 【转载】C#中ArrayList集合类使用Add方法添加元素
ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,因此使用Ar ...
- ArrayList的使用方法(转载)
转载自: http://i.yesky.com/bbs/jsp/view.jsp?articleID=889992&forumID=150 1.什么是ArrayList ArrayLis ...
- Java-集合(没做出来)第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列。 例如: List list = new ArrayList(); list.add(“Hello”); list.add(“World”); list.add(“Learn”); //此时list 为Hello World Learn reverseL
没做出来 第四题 (List)写一个函数reverseList,该函数能够接受一个List,然后把该List 倒序排列. 例如: List list = new ArrayList(); list.a ...
- ArrayList 排序Sort()方法扩展
1.sort() sort可以直接对默认继承 IComparable接口的类进行排序,如:int.string.... ArrayList arrayList = new ArrayList(); , ...
- ArrayList的使用方法【转载】
*** Source URL: http://i.yesky.com/bbs/jsp/view.jsp?articleID=889992&forumID=150 *** 1.什么是ArrayL ...
- 如何巧妙的使用ArrayList的Clone方法
一.ArrayList的Clone方法的源码 返回一个Object对象,所以在使用此方法的时候要强制转换. ArrayList的本质是维护了一个Object的数组,所以克隆也是通过数组的复制实现的,属 ...
- C# ArrayList的使用方法小总结
1.什么是ArrayList ArrayList就是传说中的动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了如下一些好处: 动态的增加和减少元素 实现了ICollection和ILis ...
随机推荐
- KVM虚拟化知识的一些笔记
一.KVM介绍 KVM:运行在内核空间,提供CPU 和内存的虚级化,以及客户机的 I/O 拦截.Guest 的 I/O 被 KVM 拦截后,交给 QEMU 处理. QEMU:修改过的为 KVM 虚机使 ...
- js onload事件使用
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...
- OPENGL---Ps 径向模糊算法(glsl)
原文:OPENGL---Ps 径向模糊算法(glsl) 本文转载自: http://blog.csdn.net/zx6733090/article/details/40311689 功能本人之前也介 ...
- Win8 Metro(C#)数字图像处理--2.47人脸红眼去除算法
原文:Win8 Metro(C#)数字图像处理--2.47人脸红眼去除算法 [函数名称] 红眼去除 RedeyeRemoveProcess(WriteableBitmap src) ...
- C# TIFF图像开发
NuGet安装控件: Install-Package BitMiracle.LibTiff.NET -Version 实现代码: private BitmapSource TiffToBitmap(s ...
- Android零基础入门第41节:使用SimpleAdapter
原文:Android零基础入门第41节:使用SimpleAdapter 通过ArrayAdapter实现Adapter虽然简单.易用,但ArrayAdapter的功能比较有限,它的每个列表项只能给一个 ...
- Tensorflow进阶
第一章 图像领域,第\(i\)类图片提取到的特征: \[ feature_i=\sum_jw_{i,j}x_j+b_i \] 其中,\(j\)表示一张图片的第\(j\)个像素,\(b_i\)是偏置值( ...
- SSL Converter & Formats
https://www.sslshopper.com/ssl-converter.html PEM Format The PEM format is the most common format th ...
- 设置windows2008系统缓存大小限制,解决服务器运行久了因物理内存耗尽出僵死(提升权限后,使用SetSystemFileCacheSize API函数,并将此做成了一个Service)
声明: 找到服务器僵死的原因了,原因是虚拟内存设置小于物理内存. 只要虚拟内存设置为系统默认大小就不会出生僵死的现象了. 当时因为服务器内存48G,系统默认虚拟内存大小也是48G, 觉得太占硬盘空间, ...
- 关于qtcreator+vs2008+CDB调试太卡的问题研究(载入符号表,以及VS调试器的注册表信息)
在刚接触Qt时,对于较大的项目,用qtcreator + vs + cdb 调试时,启动很慢并且单步运行时也经常会出现卡住半分钟以上的情况,一直没有解决.在需要debug的时候大多会在vs2008上安 ...