一、对于ArrayList需要掌握的七点内容
- ArrayList的创建:即构造器
- 往ArrayList中添加对象:即add(E)方法
- 获取ArrayList中的单个对象:即get(int index)方法
- 删除ArrayList中的对象:即remove(E)方法
- 遍历ArrayList中的对象:即iterator,在实际中更常用的是增强型的for循环去做遍历
- 判断对象是否存在于ArrayList中:contain(E)
- ArrayList中对象的排序:主要取决于所采取的排序算法(以后讲)
二、源码分析
2.1、ArrayList的创建(常见的两种方式)
List<String> strList = new ArrayList<String>(); List<String> strList2 = new ArrayList<String>(2);
ArrayList源代码:
基本属性:
//对象数组:ArrayList的底层数据结构 private transient Object[] elementData; //elementData中已存放的元素的个数,注意:不是elementData的容量 private int size;
构造器:
/** * 创建一个容量为initialCapacity的空的(size==0)对象数组 */ public ArrayList(int initialCapacity) { super();//即父类protected AbstractList() {} if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity:" + initialCapacity); this.elementData = new Object[initialCapacity]; } /** * 默认初始化一个容量为10的对象数组 */ public ArrayList() { this(10);//即上边的public ArrayList(int initialCapacity){}构造器 }
在我们执行new ArrayList<String>()时,会调用上边的无参构造器,创造一个容量为10的对象数组。
在我们执行new ArrayList<String>(2)时,会调用上边的public ArrayList(int initialCapacity),创造一个容量为2的对象数组。
注意:
- 上边有参构造器的super()方法是ArrayList父类AbstractList的构造方法,这个构造方法如下,是一个空构造方法:
protected AbstractList() { }
- 在实际使用中,如果我们能对所需的ArrayList的大小进行判断,有两个好处:
- 节省内存空间(eg.我们只需要放置两个元素到数组,new ArrayList<String>(2))
- 避免数组扩容(下边会讲)引起的效率下降(eg.我们只需要放置大约37个元素到数组,new ArrayList<String>(40))
2.2、往ArrayList中添加对象(常见的两个方法add(E)和addAll(Collection<? extends E> c))
2.2.1、add(E)
strList2.add("hello");
ArrayList源代码:
/** * 向elementData中添加元素 */ public boolean add(E e) { ensureCapacity(size + 1);//确保对象数组elementData有足够的容量,可以将新加入的元素e加进去 elementData[size++] = e;//加入新元素e,size加1 return true; }
/** * 确保数组的容量足够存放新加入的元素,若不够,要扩容 */ public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length;//获取数组大小(即数组的容量) //当数组满了,又有新元素加入的时候,执行扩容逻辑 if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3) / 2 + 1;//新容量为旧容量的1.5倍+1 if (newCapacity < minCapacity)//如果扩容后的新容量还是没有传入的所需的最小容量大或等于(主要发生在addAll(Collection<? extends E> c)中) newCapacity = minCapacity;//新容量设为最小容量 elementData = Arrays.copyOf(elementData, newCapacity);//复制新容量 } }
在上述代码的扩容结束后,调用了Arrays.copyOf(elementData, newCapacity)方法,这个方法中:对于我们这里而言,先创建了一个新的容量为newCapacity的对象数组,然后使用System.arraycopy()方法将旧的对象数组复制到新的对象数组中去了。
2.2.2、addAll(Collection<? extends E> c)
使用方式:
List<String> strList = new ArrayList<String>(); strList.add("jigang"); strList.add("nana"); strList.add("nana2"); List<String> strList2 = new ArrayList<String>(2); strList2.addAll(strList);
源代码:
/** * 将c全部加入elementData */ public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray();//将c集合转化为对象数组a int numNew = a.length;//获取a对象数组的容量 ensureCapacity(size + numNew);//确保对象数组elementData有足够的容量,可以将新加入的a对象数组加进去 System.arraycopy(a, 0, elementData, size, numNew);//将对象数组a拷贝到elementData中去 size += numNew;//重新设置elementData中已加入的元素的个数 return numNew != 0;//若加入的是空集合则返回false }
注意:
- 从上述代码可以看出,若加入的c是空集合,则返回false
- ensureCapacity(size + numNew);这个方法在上边讲
- System.arraycopy()方法定义如下:
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
将数组src从下标为srcPos开始拷贝,一直拷贝length个元素到dest数组中,在dest数组中从destPos开始加入先的srcPos数组元素。
2.3、获取ArrayList中的单个对象
2.4、删除ArrayList中的对象
2.5、判断对象是否存在于ArrayList中
2.6、遍历ArrayList中的对象
三、总结
- ArrayList基于数组方式实现,无容量的限制(会扩容)
临时有事儿,剩下的内容之后在写。
时间: 2024-10-13 11:54:30