java集合类源码分析之List
Posted Wilange
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java集合类源码分析之List相关的知识,希望对你有一定的参考价值。
这一节主要介绍List接口的几个实现类的区别:
1.线程安全
Vector是线程安全的,而ArrayList和LinkedList是非线程安全的。从源码中我们可知,Vector类中的方法大部分都是同步的,即被synchronized关键字修饰;而那些没有被synchronized关键字修饰的方法都是通过调用其他同步方法或者采用同步代码块来达到同步的。
1 public synchronized void addElement(E obj) { 2 modCount++; 3 ensureCapacityHelper(elementCount + 1); 4 elementData[elementCount++] = obj; 5 } 6 7 public synchronized boolean removeElement(Object obj) { 8 modCount++; 9 int i = indexOf(obj); 10 if (i >= 0) { 11 removeElementAt(i); 12 return true; 13 } 14 return false; 15 } 16 17 public synchronized E get(int index) { 18 if (index >= elementCount) 19 throw new ArrayIndexOutOfBoundsException(index); 20 21 return elementData(index); 22 } 23 24 public synchronized void insertElementAt(E obj, int index) { 25 modCount++; 26 if (index > elementCount) { 27 throw new ArrayIndexOutOfBoundsException(index 28 + " > " + elementCount); 29 } 30 ensureCapacityHelper(elementCount + 1); 31 System.arraycopy(elementData, index, elementData, index + 1, elementCount - index); 32 elementData[index] = obj; 33 elementCount++; 34 }
1 public boolean contains(Object o) { 2 return indexOf(o, 0) >= 0; 3 } 4 5 public synchronized int indexOf(Object o, int index) { 6 if (o == null) { 7 for (int i = index ; i < elementCount ; i++) 8 if (elementData[i]==null) 9 return i; 10 } else { 11 for (int i = index ; i < elementCount ; i++) 12 if (o.equals(elementData[i])) 13 return i; 14 } 15 return -1; 16 } 17 18 public Enumeration<E> elements() { 19 return new Enumeration<E>() { 20 int count = 0; 21 22 public boolean hasMoreElements() { 23 return count < elementCount; 24 } 25 26 public E nextElement() { 27 synchronized (Vector.this) { 28 if (count < elementCount) { 29 return elementData(count++); 30 } 31 } 32 throw new NoSuchElementException("Vector Enumeration"); 33 } 34 }; 35 }
2.适用条件
ArrayList:适用于随机访问比较频繁(自带索引),而插入和删除操作较少的情况下;
LinkedList:适用于插入和删除比较频繁(修改前后节点),而随机访问较少的情况下;
Vector:适用于要求线程安全(方法同步),执行效率不高,数据量大的情况下。
3.内存消耗
在内存消耗方面,LinkedList < ArrayList < Vector。
LinkedList由于采用链表的形式实现,所以不需要指定容量大小,因此内存消耗较少;而ArrayList和Vector都是采用数组的形式实现,需要指定初始容量的大小(默认都是10),并且当容量不够时都需要进行扩容,在扩容方面:
- ArrayList每次只增加当前数组长度的一半,即newCapacity = oldCapacity + (oldCapacity >> 1),源码中扩容的方法如下:
1 private void grow(int minCapacity) { 2 // overflow-conscious code 3 int oldCapacity = elementData.length; 4 int newCapacity = oldCapacity + (oldCapacity >> 1); 5 if (newCapacity - minCapacity < 0) 6 newCapacity = minCapacity; 7 if (newCapacity - MAX_ARRAY_SIZE > 0) 8 newCapacity = hugeCapacity(minCapacity); 9 // minCapacity is usually close to size, so this is a win: 10 elementData = Arrays.copyOf(elementData, newCapacity); 11 }
- Vector每次增加当前数组长度的一倍,即newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity),capacityIncrement是人为指定的扩容大小,默认为0,源码中扩容的方法如下:
1 private void grow(int minCapacity) { 2 // overflow-conscious code 3 int oldCapacity = elementData.length; 4 int newCapacity = oldCapacity + ((capacityIncrement > 0) ? 5 capacityIncrement : oldCapacity); 6 if (newCapacity - minCapacity < 0) 7 newCapacity = minCapacity; 8 if (newCapacity - MAX_ARRAY_SIZE > 0) 9 newCapacity = hugeCapacity(minCapacity); 10 elementData = Arrays.copyOf(elementData, newCapacity); 11 }
综上所述,Vector对内存的消耗比较高,其次是ArrayList。
4.集合排序
有了数据的存储方法(集合),当然要考虑到数据在集合中的顺序问题,下面对集合排序做一个简单的总结:
- 集合中的排序通常调用Collections类中的静态方法来实现,常用的方法有:sort、reverse、shuffle、min、max等。
1 LinkedList<Integer> linkedList = new LinkedList<Integer>(); 2 linkedList.add(100); 3 linkedList.add(120); 4 linkedList.add(110); 5 Collections.sort(linkedList);//升序排列 6 System.out.println(linkedList); 7 8 Collections.sort(linkedList, new Comparator<Integer>() { 9 10 @Override 11 public int compare(Integer o1, Integer o2) { 12 // TODO Auto-generated method stub 13 // return 0; 14 return o2.compareTo(o1); //降序排列 15 } 16 }); 17 System.out.println(linkedList); 18 19 Collections.shuffle(linkedList);//随机乱序 20 System.out.println(linkedList); 21 22 Collections.reverse(linkedList);//逆序 23 System.out.println(linkedList); 24 25 System.out.println(Collections.min(linkedList));//最小值 26 System.out.println(Collections.max(linkedList));//最大值
这里只给出了LinkedList的排序代码,而对于ArrayList和Vector的排序也是同样的操作,此处不再赘述。
以上是关于java集合类源码分析之List的主要内容,如果未能解决你的问题,请参考以下文章