看到过相关的JVM运行时性能问题的优化,包括许多使用局部变量、StringBuffere、少用二维数组、尽量使用System.arraycopy()代替通过来循环复制数组、少用synchronized、适当场合使用单例模式开发……现在就关于在你的java程序中使用列表项目Arrays、ArrayList、LinkedList、Vector的性能及底层数据结构分析:
1、Array:简单的数组,可以通过int [] a=new int[100]这种方式来实例化一个数组对象,这个对象将会保持在heap memory(堆内存)中。
2、ArrayList: 这个类相当于线性表结构,用java实现是通过数组,也就是数据结构中的静态线性表,下面是关于它在java中的内部实现部分代码可以看出:
private int size;
/**
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @exception IllegalArgumentException if the specified initial capacity
* is negative
*/
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
还有一个内部的add()方法的实现,实际上就是一个数组的操作:
/**
* Inserts the specified element at the specified position in this
* list. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
ensureCapacity(size+1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
下面写一个测试案例分析一下它的执行效率:
import java.util.*;
public class ArrayList_test{
public static void main(String[] args){
Date d1=new Date();
long dbefore=d1.getTime();
List<Integer> list=new ArrayList();
for(int i=0;i<10000;i++){
list.add(i);
}
for(int i=1;i<5000;i++){
list.add(5000-i,i);
}
Date d2=new Date();
long dafter=d2.getTime();
long time=dafter-dbefore;
System.out.println("Time="+time+"ms");
}
}
运行:52ms
3、LinkedList:它是一个链表结构,在C语言中实现是通过指针实现,java中对它是实现了一个双链表结构,是对象的引用来实现类似的指针功能:
private transient Entry<E> header = new Entry<E>(null, null, null);
private transient int size = 0;
/**
* Constructs an empty list.
*/
public LinkedList() {
header.next = header.previous = header;
}
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
包含的内部类:
private static class Entry<E> {
E element;
Entry<E> next;
Entry<E> previous;
Entry(E element, Entry<E> next, Entry<E> previous) {
this.element = element;
this.next = next;
this.previous = previous;
}
具体的出入操作就不多说:就是根据这几个类似指针功能的对象的调用完成,对于他的性能也有下面的分析:
import java.util.*;
public class LinkedList_test{
public static void main(String[] args){
Date d1=new Date();
long dbefore=d1.getTime();
List<Integer> link=new LinkedList();
for(int i=0;i<10000;i++){
link.add(i);
}
for(int i=1;i<5000;i++){
link.add(5000-1,i);
}
Date d2=new Date();
long dafter=d2.getTime();
long time=dafter-dbefore;
System.out.println("Time="+time+"ms");
}
}
运行下:time=154ms
,这链表的实现底层通过许多对象间调用实现,占用内存多,效率较低。
3、Vector:它的实现和ArrayList差不多,只是vector采用的是同步机制,有时效率会低点,是具体情况吧。
/**
* Constructs an empty vector with the specified initial capacity and
* capacity increment.
*
* @param initialCapacity the initial capacity of the vector
* @param capacityIncrement the amount by which the capacity is
* increased when the vector overflows
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
操作测试:
import java.util.*;
public class Vector_test{
public static void main(String[] args){
Date d1=new Date();
long dbefore=d1.getTime();
Vector<Integer> v=new Vector();
for(int i=0;i<10000;i++){
v.add(i);
}
for(int i=1;i<5000;i++){
v.add(5000-1,i);
}
Date d2=new Date();
long dafter=d2.getTime();
long time=dafter-dbefore;
System.out.println("Time="+time+"ms");
}
}
运行结果:time=
以上就是所有测试结果及分析,所以在一般小列表操作,直接一个数组实现应该没问题,对于数据结构复杂的列表,建议适应ArrayList。