积千里跬步,汇万里江河;每天进步一点点,终有一天将成大佬。
当然ArrayList里的方法不止这些,本文主要讲一些常用的方法
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
的主要方法,平时用的也是最多的方法之一,所以源码比较复杂,比较长
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的方法流程就走完了,其核心步骤:
第一次 原大小的1.5倍 System.arraycopy()
该方法为在指定位置插入元素,该位置及后面所有元素后移
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)
插入方法其主要步骤如下:
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方法比较简单,主要步骤为:
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
主要用户内部类的迭代器