Java基础之Collection的ArrayList
- 一、add()与addAll()
- 二、remove()
- 三、trimToSize()
- 1、案例
一、add()与addAll()
跟C++ 的vector不同,ArrayList没有push_back()
方法,对应的方法是add(E e)
,ArrayList也没有insert()
方法,对应的方法是add(int index, E e)
。这两个方法都是向容器中添加新元素,这可能会导致capacity不足,因此在添加元素之前,都需要进行剩余空间检查,如果需要则自动扩容。扩容操作最终是通过grow()
方法完成的。
add(int index, E e)
需要先对元素进行移动,然后完成插入操作,也就意味着该方法有着线性的时间复杂度。
addAll()
方法能够一次添加多个元素,根据位置不同也有两个版本,一个是在末尾添加的addAll(Collection<? extends E> c)
方法,一个是从指定位置开始插入的addAll(int index, Collection<? extends E> c)
方法。跟add()
方法类似,在插入之前也需要进行空间检查,如果需要则自动扩容;如果从指定位置插入,也会存在移动元素的情况。 addAll()
的时间复杂度不仅跟插入元素的多少有关,也跟插入的位置相关。
二、remove()
remove()
方法也有两个版本,一个是remove(int index)
删除指定位置的元素,另一个是remove(Object o)
删除第一个满足o.equals(elementData[index])
的元素。删除操作是add()
操作的逆过程,需要将删除点之后的元素向前移动一个位置。需要注意的是为了让GC起作用,必须显式的为最后一个位置赋null
值。
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved);
elementData[--size] = null; //清除该位置的引用,让GC起作用
return oldValue;
}
三、trimToSize()
我们知道ArrayList中默认初始容量是10,当添加的元素个数大于10后,会自动扩容,容量变为原来的1.5倍,也就是说elementData数组的长度是15,但如果在添加10个元素之后,只添加了1个元素,现在ArrayList的size其实是11,但elementData数组的length却是15,那么还有4个数组空间没有利用起来,浪费资源,就可以调用该方法调整elementData数组,将其设置为length等于size的数组,底层是复制了一个长度为size的elementData数组返回。
ArrayList还给我们提供了将底层数组的容量调整为当前列表保存的实际元素的大小的功能。它可以通过trimToSize方法来实现。代码如下:
/**
* Trims the capacity of this <tt>ArrayList</tt> instance to be the
* list's current size. An application can use this operation to minimize
* the storage of an <tt>ArrayList</tt> instance.
*/
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
1、案例
@SpringBootTest
public class ListTests {
@Test
void test1() throws Exception {
ArrayList<String> stringArrayList = new ArrayList<>();
//初始化时获取
System.out.println("初始化时获取");
getArrayListLength(stringArrayList);
stringArrayList.add("abc");
stringArrayList.add("bbc");
stringArrayList.add("cba");
stringArrayList.add("cac");
//存入值后获取
System.out.println("存入值后获取");
getArrayListLength(stringArrayList);
//调用trimToSize()后获取
System.out.println("调用trimToSize()后获取");
stringArrayList.trimToSize();
getArrayListLength(stringArrayList);
}
//查看ArrayList集合容量方法 -- 反射
public static void getArrayListLength(List list) throws Exception {
//获取Class对象
Class c = Class.forName("java.util.ArrayList");
//映射Class对象所表示类的属性
Field field = c.getDeclaredField("elementData");
//设置访问表示为true
field.setAccessible(true);
//返回指定对象上此 Field 表示的字段的值
Object[] object = (Object[]) field.get(list);
//获取实际长度与容量
System.out.println(list.size());
System.out.println(object.length);
}
}
- 人不需要活太多样子。你认真做一件事,会解释所有的事。
- 愿所有的有情人,皆成眷属。
- 露一露笑脸,让烦恼无处藏身,露一露幸福,让忧愁远走他乡,露一露快乐,让郁闷自惭形*,露一露真诚,让祝福传遍千里,寒露节,愿你展露笑颜,开心无限!
- 愿你路过形形色色,不忘内心纯澈。
- 愿你有前进一寸的勇气,亦有后退一尺的从容。
- 每个人都有属于自己的舞台,这个舞台,是那么光灿,美丽,生命从此辉煌无悔!只要坚韧不拔的走下去!
- 只有靠你自己的双手,才能搬来生命的障碍。
- 圣诞到了,祝您的身体像圣诞老人一样健康,事业像雪橇车一样没有阻力,钞票像圣诞老人包袱里的礼物一样无穷无尽!
- 保持前进,丝毫别在乎别人想什么说什么,做你自己必须做的,为自己。
- 活在这珍贵的人间,太阳强烈,水波温柔。――海子