【java基础】List
2016-02-24 15:27
495 查看
1.概括
1. ArrayList是实现List接口的动态数组,动态就是大小可变。是线程不安全的,适用于查找速度快,对插入删除慢的场景。创建时默认初始容量为10。随着ArrayList中元素的增加,它的容量也会不断的自动增长。每次添加元素时都会判断是否需要扩容,扩容后会进行数组的重新拷贝
2. LinkedList是基于链表的实现方式,同样实现List接口,是线程不安全的。适用于查找速度慢,对插入删除要求快的场景。LinkedList在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。
3. Vector可以实现可增长的对象数组,实现List接口。与数组一样,它包含可以使用整数索引进行访问的组件。不过,Vector的大小是可以增加或者减小的,以便适应创建Vector后进行添加或者删除操作。实现了List接口,是线程安全的。跟ArrayList一样,添加元素也是要判断是否需要扩容并进行数组的重新拷贝。
4. Stack是先进后出的对象堆栈,继承自Vector,并通过empty(),peek(),pop(),push(E item),search(Object o)进行扩展。
2.效率
1. ArrayList
arraycopy这个方法将源数组src的第srcPos位置开始的length个元素移动到目标数组dest的第destPos个位置开始的length个位置。是非常耗时和效率低的操作。故ArrayList不适合插入频繁的场景。
2.LinkedList
增加元素时index等于size则插在末尾,否则调用linkBefore
查找index具体位置时调用了node(int index)方法,提高了查找index对应节点的效率,因为使用位移操作来判断从头部还是尾部开始找。
3.Vector
Vector内部也是跟ArrayList一样,用动态数组实现,所以效率差不多,只是Vector是线程安全的。
3.容量扩容
Vector和ArrayList一样都使用动态数组,故增加元素的时候有时可能需要扩容操作。ArrayList使用ensureCapacityHelper(int minCapacity)方法。Vector调用ensureCapacity(int
minCapacity)的同步方法,方法内部再调用了ensureCapacityHelper(int minCapacity)方法。
它们容量扩容的逻辑都在grow方法中
(1)ArrayList的ensureCapacityHelper(int minCapacity)
ArrayList的ensureCapacityHelper(int minCapacity)最后调用了grow(int minCapacity),并将容量扩展为原来的1.5倍
(2)Vector
Vector扩展容量是根据capacityIncrement的,若容量增量系数(capacityIncrement) > 0,则将容器大小增加到capacityIncremen他,否则将容量增加一倍
1. ArrayList是实现List接口的动态数组,动态就是大小可变。是线程不安全的,适用于查找速度快,对插入删除慢的场景。创建时默认初始容量为10。随着ArrayList中元素的增加,它的容量也会不断的自动增长。每次添加元素时都会判断是否需要扩容,扩容后会进行数组的重新拷贝
2. LinkedList是基于链表的实现方式,同样实现List接口,是线程不安全的。适用于查找速度慢,对插入删除要求快的场景。LinkedList在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。
3. Vector可以实现可增长的对象数组,实现List接口。与数组一样,它包含可以使用整数索引进行访问的组件。不过,Vector的大小是可以增加或者减小的,以便适应创建Vector后进行添加或者删除操作。实现了List接口,是线程安全的。跟ArrayList一样,添加元素也是要判断是否需要扩容并进行数组的重新拷贝。
4. Stack是先进后出的对象堆栈,继承自Vector,并通过empty(),peek(),pop(),push(E item),search(Object o)进行扩展。
2.效率
1. ArrayList
public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); //扩容操作 System.arraycopy(elementData, index, elementData, index + 1, size - index);//数组拷贝 elementData[index] = element; //插入 size++; }
arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
arraycopy这个方法将源数组src的第srcPos位置开始的length个元素移动到目标数组dest的第destPos个位置开始的length个位置。是非常耗时和效率低的操作。故ArrayList不适合插入频繁的场景。
2.LinkedList
增加元素时index等于size则插在末尾,否则调用linkBefore
public void add(int index, E element) { checkPositionIndex(index); if (index == size) //插入位置在末尾 linkLast(element); else linkBefore(element, node(index)); }
查找index具体位置时调用了node(int index)方法,提高了查找index对应节点的效率,因为使用位移操作来判断从头部还是尾部开始找。
Node<E> node(int index) { if (index < (size >> 1)) { //size右移一位也就是如果index 小于 size/2 则从头开始查找 Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { //如果index 大于 size/2 则从尾部开始查找 Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } }
3.Vector
Vector内部也是跟ArrayList一样,用动态数组实现,所以效率差不多,只是Vector是线程安全的。
3.容量扩容
Vector和ArrayList一样都使用动态数组,故增加元素的时候有时可能需要扩容操作。ArrayList使用ensureCapacityHelper(int minCapacity)方法。Vector调用ensureCapacity(int
minCapacity)的同步方法,方法内部再调用了ensureCapacityHelper(int minCapacity)方法。
它们容量扩容的逻辑都在grow方法中
(1)ArrayList的ensureCapacityHelper(int minCapacity)
public void ensureCapacity(int minCapacity) { int minExpand = (elementData != EMPTY_ELEMENTDATA) // any size if real element table ? 0 // larger than default for empty table. It's already supposed to be // at default size. : DEFAULT_CAPACITY; if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //ArrayList容量大小 int newCapacity = oldCapacity + (oldCapacity >> 1); //扩容后的容量为旧容量的1.5倍 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
ArrayList的ensureCapacityHelper(int minCapacity)最后调用了grow(int minCapacity),并将容量扩展为原来的1.5倍
(2)Vector
Vector扩展容量是根据capacityIncrement的,若容量增量系数(capacityIncrement) > 0,则将容器大小增加到capacityIncremen他,否则将容量增加一倍
public synchronized void ensureCapacity(int minCapacity) { if (minCapacity > 0) { modCount++; ensureCapacityHelper(minCapacity); } }
private void ensureCapacityHelper(int minCapacity) { // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);//<span style="font-family: Calibri;">capacityIncrement<0则新容量为原来的2倍,否则增加capacityIncrement</span> if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); }
相关文章推荐
- MyEclipse10.7.1解决项目打war包失败
- Struts2 struts标签
- Java IO技术
- Java基础03 构造器与方法重载
- RxJava操作符-subscribeOn
- (JavaCard) 技术入门 2 -- 搭建JCDK开发环境-Java Card 3.0.5
- java便捷开发
- Spring-web源码解析之Filter-AbstractRequestLoggingFilter
- java装饰者模式
- Eclipse批量修改
- (JavaCard) 技术入门 1 -- 名词普及
- spring No default constructor found; nested exception is java.lang.NoSuchMethodException: com.slj.mo
- Struts2 OGNL表达式
- Java八种基本数据类型所占字节
- selenium 学习笔记 ---新手学习记录(7) 问题总结(java)
- eclipse 创建maven 项目 动态web工程完整示例
- Java 去掉字符串中的换行符回车符等
- Java 去掉字符串中的换行符回车符等
- Java 去掉字符串中的换行符回车符等
- spring-security配置和原理简介