积千里跬步,汇万里江河;天天进步一点点,终有一天将成大佬。
固然ArrayList里的方法不止这些,本文主要讲一些经常使用的方法java
Arraylist
里的方法变量主要有如下几个数组
List<String> list=new ArrayList<>(5);
其实这个就至关于把传入的list对象里的数据复制
到新的ArrayList对象工具
List<String> list=new ArrayList<>(Arrays.asList("z","m","h"));
这里用来Arrays
工具类里的asList
方法,它的源码里是直接返回一个List,有兴趣的能够去看看,这里就不介绍了
这个比较简单,直接赋值一个空数组源码分析
List<String> list=new ArrayList<>();
add通常经常使用的有两个方法,一个就是add(E e)
在尾部添加数据,一个就是add(int index,E element)
在指定位置插入元素性能
这个是Arrayist
的主要方法,平时用的也是最多的方法之一,因此源码比较复杂,比较长spa
List<String> list=new ArrayList<>(); list.add("灰灰HK");
ensureCapacityInternal(int minCapacity)
确保数组容量充足calculateCapacity(Object[] elementData, int minCapacity)
ensureExplicitCapacity(int minCapacity)
这个方法,这个方法先修改次数加1
,而后判断size+1
是否是比当前的数组容量大,若是比当前的数组容量大,则进行扩容操做,扩大容量为原数组的1.5倍
好比第二次调用add方法,此时size+1=2
,elementData.length=10
,为何等于10呢?由于第一次默认把数组容量从0扩大到了10,这时size+1
比elementData.length
小,就不会进行扩容操做
grow(int minCapacity)
扩容这里调用Arrays.copyOf()
方法进行复制操做,当进一步深刻这个方法时,发现是由System.arraycopy()
这个方法实现复制功能的,这个方法由native
关键字修饰,表示不是由Java
语言实现的,通常是c/cpp实现
到这里,add的方法流程就走完了,其核心步骤:3d
第一次
添加元素,把数组容量扩容到10原大小的1.5倍
System.arraycopy()
方法把原数组的元素复制到扩容后的新数组该方法为在指定位置插入元素,该位置及后面全部元素后移code
List<String> list=new ArrayList<>(); list.add("hk"); list.add(0,"灰灰");
能够看到,这边又用到了
System.arraycopy()
这个方法
rangeCheckForAdd(int index)
判断是否越界这里他是和size
对比,而不是和数组的length
对比,我我的认为这样第一节省了空间,第二方便后面移动的操做
System.arraycopy()
拷贝数组public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
- src 原数组对象
- srcPos 原数组起始位置
- dest 目标数组
- destPos 目标数组起始位置
- length 复制多少个数据
插入方法其主要步骤以下:对象
System.arraycopy()
进行index
及后面的元素后移List<String> list=new ArrayList<>(); list.add("hk"); list.get(0);
rangeCheck(int index)
判断是否越界get个add方法判断越界的方法是不同的,这边是index>=size
,多了个等于
,为何要多个等于呢?由于数组是从0开始的,而size至关于
是开始的从1开始的
private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
elementData(int index)
直接返回对应下标的数组元素E elementData(int index) { return (E) elementData[index]; }
get方法比较简单,主要步骤为:blog
List<String> list=new ArrayList<>(); list.add("hk"); list.set(0,"灰灰");
List<String> list=new ArrayList<>(); list.add("hk"); list.remove(0);
当删除的元素为最后一个元素时,
numMoved
就小于0了,就不会进行移动元素的操做
这个方法在实际中用的比较少,由于AraryList
是能够保存重复的元素,因此删除是删除最先添加的元素
List<String> list=new ArrayList<>(); list.add("hk"); list.remove("hk");
fastRemove(int index)
删除元素这个方法和remove(int index)内部的操做相似,不过这边不保存被删除的元素
private void fastRemove(int index) { modCount++; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work }
List<String> list=new ArrayList<>(); list.add("hk"); list.clear();
ArrayList
底层扩容或者移动数组元素时都调用了System.arraycopy()
来进行相关操做,平时进行咱们进行数组复制或移动的时候也能够调用这个方法了,这个性能比循环复制性能高多了,特别是在大量数据的时候。
文章好几回出现了modCount++
这个操做,这个modCount
主要用户内部类的迭代器