iamhuzl

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  1 随笔 :: 13 文章 :: 21 评论 :: 0 Trackbacks
   Java面试中关于容器类List,Set是必问题目。但在我的面试经历中很难遇到满意的答复。大部分只能了解其大概使用方法,对其内部结构缺乏了解,错误的使用方式会导致性能大幅下降。
   首先介绍ArrayList,顾名思义内部数据结构是数组
   private transient Object[] elementData;
   private int size;
   public ArrayList(int initialCapacity){
   }

   在增加元素时,若容量不足进行扩充
    public void ensureCapacity(int minCapacity) {
	modCount++;
	int oldCapacity = elementData.length;
	if (minCapacity > oldCapacity) {
	    Object oldData[] = elementData;
	    int newCapacity = (oldCapacity * 3)/2 + 1;
    	    if (newCapacity < minCapacity)
		newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
	}
    }

   新数组大小为之前数组大小*1.5+1 ,加上1保证oldCapacity为1的情况也能扩充为2
  (类似分页时总页数=(总记录数+ (每页记录数-1))/每页记录数算法)

   删除元素时通过 System.arraycopy把删除位置后的所有元素前移一个位置实现
public E remove(int index) {
	RangeCheck(index);

	modCount++;
	E oldValue = (E) elementData[index];

	int numMoved = size - index - 1;
	if (numMoved > 0)
	    System.arraycopy(elementData, index+1, elementData, index,
			     numMoved);
	elementData[--size] = null; // Let gc do its work

	return oldValue;
    }

 
 
  LinkedList大家都知道是通过链表实现,内部是一个双向链表
public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    private transient Entry<E> header = new Entry<E>(null, null, null);
    private transient int size = 0;
}
private static class Entry<E> {
	E element;
	Entry<E> next;
	Entry<E> previous;
}

插入和删除都只要改动前后节点的next和previous实现

总结特点如下:
类型内部结构顺序遍历速度随机遍历速度追加代价插入代价删除代价占用内存
ArrayList数组
LinkedList双向链表

所以:
  • 一般顺序遍历情况下使用ArrayList,但注意构造函数中设置初始大小
  • 尽量不对ArrayList进行插入或删除操作(删除尾部除外),若有多次删除/插入操作又有随机遍历的需求,可以再构建一个ArrayList,把复合条件的对象放入新ArrayList,而不要频繁操作原ArrayList
  • 经常有删除/插入操作而顺序遍历列表的情况下最适合使用LinkedList


 

已有 0 人发表留言,猛击->>这里<<-参与讨论


ITeye推荐



posted on 2012-05-14 15:20 温水青蛙 阅读(2920) 评论(2)  编辑  收藏

评论

# re: ArrayList,LinkedList使用场景及性能说明 2013-12-24 15:20 ArvinRong
•经常有删除/插入操作而顺序遍历列表的情况下最适合使用LinkedList 更准确的说是不是应该是同时存在大量在头部和尾部插入数据并顺序遍历的情况下适合使用LinkedList。因为在中部插入数据时在万级数据单位时LinkedList性能不如ArrayList,而且差距很大,但是在头部插入时虽然LinkedList性能比较好,但是跟ArrayList差距并没有特别的大。所以即使是在经常有插入删除操作时有的时候ArrayList是更好的选择,另外当数据量不是特别大的时候ArrayList插入性能整体都高于LinkedList。  回复  更多评论
  

# re: ArrayList,LinkedList使用场景及性能说明 2014-01-23 10:33 温水青蛙
【因为在中部插入数据时在万级数据单位时LinkedList性能不如ArrayList,而且差距很大】
实测在元素数量为10万列表中插入1000个元素,LinkedList(369ms)性能是ArrayList(11965ms)的300多倍。
插入或删除中间元素时ArrayList 都必须迁移该位置之后的所有元素  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: