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 ...
随机推荐
- WPF里的一些Effect特效
原文:WPF里的一些Effect特效 Blend的特效都在Microsoft.Expression.Media.Effects里,用之前添加一下引用. 可以在前台选中对象后直接点击Effect新建一种 ...
- WPF DataTemplateSelector的使用
<Window x:Class="CollectionBinding.MainWindow" xmlns="http://schemas.micros ...
- AY写给国人的教程- VS2017 Live Unit Testing[1/2]-C#人爱学不学-aaronyang技术分享
原文:AY写给国人的教程- VS2017 Live Unit Testing[1/2]-C#人爱学不学-aaronyang技术分享 谢谢大家观看-AY的 VS2017推广系列 Live Unit Te ...
- .Net中使用数据库(sqlite)的大体流程(简单向)
说来数据库,各种语言各种数据库在操作上大体无异,基本都是连接数据库.操作数据库.关闭数据库连接的流程,不过Sqlite由于是单文件数据库,相比其他服务器的数据库连接更简单,只需要给定数据库文件的路径即 ...
- Interactive Data Display如何显示菜单?
貌似直接跟其它控件一样添加菜单就行了. 不过这个版本已经取消了默认菜单,所有的菜单功能都得自己去实现.
- Android零基础入门第54节:视图切换组件ViewSwitcher
原文:Android零基础入门第54节:视图切换组件ViewSwitcher 前面三期学习了ProgressBar系列组件,那本期开始一起来学习ViewAnimator组件. 一.ViewAnimat ...
- HTML 滚动条实现
##在对应的div中,添加overflow,固定高度为400px<div class="panel-body" style="height: 400px; over ...
- C++ 标准库概览(一分钟就看完了)
C++ 标准库以若干头文件的方式提供. 下面简单介绍一个各头文件的内容. 第一部分 容器 Containers <array> C++11 新增.提供了容器类模板 std::array,固 ...
- 一定要在commit之前做RAR备份,这样在出问题的时候,可以排除别人代码的干扰
否则找错实在是太痛苦了,根本不知道来自哪里...而这样上面那样做,可以节省时间.
- einsum:爱因斯坦求和约定
在Tensorflow.Numpy和PyTorch中都提供了使用einsum的api,einsum是一种能够简洁表示点积.外积.转置.矩阵-向量乘法.矩阵-矩阵乘法等运算的领域特定语言.在Tensor ...