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. html5 命运之轮生产

    码,如以下: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEn ...

  2. 【C#/WPF】调节图像的HSL(色相、饱和度、明亮度)

    原文:[C#/WPF]调节图像的HSL(色相.饱和度.明亮度) 先说概念: HSL是一种描述颜色的方式(其他颜色描述方式还有大家熟悉的RGB值).HSL三个字母分别表示图像的Hue色相.Saturat ...

  3. redis 从0 到 1 键值相关命令 服务器相关命令

    keys * 获取所有的key   忽略其数据类型 数据为空   返回(empty list or set) keys a* .*b 获取以a开头 或者 以b结尾的key 返回(empty list ...

  4. WPF DataTemplateSelector的使用

    <Window x:Class="CollectionBinding.MainWindow"        xmlns="http://schemas.micros ...

  5. Wpf发送接收 win32消息

    #region WPF发送和接收win32消息 public const int WM_GETTEXT = 0x0D; public const int WM_SETTEXT = 0x0C; publ ...

  6. Win8 Metro(C#)数字图像处理--2.68图像最小值滤波器

    原文:Win8 Metro(C#)数字图像处理--2.68图像最小值滤波器 /// <summary> /// Min value filter. /// </summary> ...

  7. PE格式大图

  8. Win10《芒果TV - Preview》更新至v3.1.57.0:热门节目和电视台直播回归

    Win10<芒果TV - Preview>是Win10<芒果TV>官方唯一指定内测预览版,最新的改进和功能更新将会在此版本优先体验. 为了想让大家能在12月31日看到<湖 ...

  9. SQLServer 以备份初始化订阅

    原文:SQLServer 以备份初始化订阅 在创建事务复制时,如果发布数据库很大,使用快照初始化时,将等待很久,如果出现问题可能又得重新初始化.使用备份初始化会省很多时间,但是数据库在创建发布订阅期间 ...

  10. Linux日志系统

    常见的日志 常见的日志一般存储在/var/log中.常见的日志查看使用:ls/ll,cat/more/less查看即可:wtmp,lastlog使用last和lastlog提取其信息即可 配置日志 较 ...