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方法实现的更多相关文章

  1. 关于ArrayList add()方法 中的引用问题

    ArrayList的add方法每次添加一个对象时,添加 的是一个对象的引用,比如进行循环操作10次  lists.add(a) 每次 a会改变 ,这时候你会发现你在lists里添加了10个相同的对象a ...

  2. ArrayList的add(E e)方法与扩容

    ArrayList是Java开发中经常用到的集合类,它是List接口的实现类,具有很高的查询性能,但不是线程安全的.本文主要讲述了ArrayList的add(E e)方法及该方法中涉及到的容量扩容技术 ...

  3. 【转载】C#中ArrayList集合类使用Add方法添加元素

    ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,因此使用Ar ...

  4. ArrayList的使用方法(转载)

    转载自: http://i.yesky.com/bbs/jsp/view.jsp?articleID=889992&forumID=150 1.什么是ArrayList    ArrayLis ...

  5. 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 ...

  6. ArrayList 排序Sort()方法扩展

    1.sort() sort可以直接对默认继承 IComparable接口的类进行排序,如:int.string.... ArrayList arrayList = new ArrayList(); , ...

  7. ArrayList的使用方法【转载】

    *** Source URL: http://i.yesky.com/bbs/jsp/view.jsp?articleID=889992&forumID=150 *** 1.什么是ArrayL ...

  8. 如何巧妙的使用ArrayList的Clone方法

    一.ArrayList的Clone方法的源码 返回一个Object对象,所以在使用此方法的时候要强制转换. ArrayList的本质是维护了一个Object的数组,所以克隆也是通过数组的复制实现的,属 ...

  9. C# ArrayList的使用方法小总结

    1.什么是ArrayList ArrayList就是传说中的动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了如下一些好处: 动态的增加和减少元素 实现了ICollection和ILis ...

随机推荐

  1. sql server 2016 JSON 学习笔记

    虽然现在win服务器已经几乎不用了,但是网上看到2016开始原生支持json 还是想试试 建立一个表  id int , json varchar(2000) json字段中输入数据 {"r ...

  2. WPF 中动态创建和删除控件

    原文:WPF 中动态创建和删除控件 动态创建控件 1.容器控件.RegisterName("Name",要注册的控件)   //注册控件 2.容器控件.FindName(" ...

  3. style的继承

    第一种方式:瞄准控件的基类 如下例所示,继承ContentControl的控件,都可以使用这个Style <Window.Resources> <Style x:Key=" ...

  4. openFrameworks 是一个旨在助力你进行开创性工作的开源 C++ 工具箱(是很多其它类库的组合)

    openFrameworks 是一个旨在助力你进行开创性工作的开源 C++ 工具箱,提供了简单且直观的实验框架.该工具箱具有常见的工具,并集合了众多常见的库: OpenGL, GLEW, GLUT,  ...

  5. GIS基础软件及操作(十二)

    原文 GIS基础软件及操作(十二) 练习十二. ArcMap制图-地图版面设计 设置地图符号-各种渲染方式的使用 使用ArcMap Layout(布局)界面制作专题地图 将各种地图元素添加到地图版面中 ...

  6. 程序异常崩溃后用windbg辅助调试解决的经验 以及 堆栈问题调试经验

    1,程序异常崩溃后用windbg辅助调试解决的经验  状况:我的程序调用别人的库做 文件写入工作. 在这一过程中出现异常,程序崩溃. 经反复检查,认为自己的程序没有错,但无法判断在别人库里哪里有错. ...

  7. 记一次ASP.NET MVC4 升级到MVC5的小问题解决

    原文:记一次ASP.NET MVC4 升级到MVC5的小问题解决 .NET 4.0 MVC4版本,升级到.NET 4.6.1 MVC5: 1.使用nuget更新所有 与mvc相关的类库; 2.更改~/ ...

  8. WebGL场景的两种地面构造方法

    总述:大部分3D编程都涉及到地面元素,在场景中我们使用地面作为其他物体的承载基础,同时也用地面限制场景使用者的移动范围,还可以在通过设置地块的属性为场景的不同位置设置对应的计算规则.本文在WebGL平 ...

  9. mogodbshell中数组对象查询修改方法

    在mongodb中,存在如下数据 { "_id" : ObjectId("59af55078a8fc5e51ff425de"), "title&quo ...

  10. 记一次在win2008下添加nginx自启动服务的操作

    为了在win环境下添加nginx自启服务,我度娘了, 找到在cnblogs下(http://www.cnblogs.com/JayK/p/3429795.html)有篇文章是介绍如何添加nginx到w ...