java集合源码之List-ArrayList

来源:互联网 发布:mysql获取date当前时间 编辑:程序博客网 时间:2024/05/16 05:45

ArrayList是JAVA集合框架List接口的一个实现类,ArrayList是我们使用最多的List集合,它的特点是:

1.首先基于动态数组的实现,容量可自动增长,初始容量为10.获取元素迅速,插入、删除操作耗时

2.非线程安全,创建线程安全的ArrayList可以使用Collections.synchronizedList或者并发包下的CopyOnWriteArrayList类 ArrayList map = Collections.synchronizedList(new ArrayList());

3.容量不固定,想放多少就放多少(当然有最大阈值,一般达不到)

4.有序的(元素输出顺序与输入顺序一致)

5.元素可以null

继承关系:


继承AbstractList抽象类,实现List接口,是数组队列,提供了相关的插入、删除、查询等操作

实现RandomAccess接口,支持快速随机访问

实现java.io.Serialization接口,支持序列化

实现Cloneable接口,支持对象克隆,浅复制

属性

//初始容量为10
private static final int DEFAULT_CAPACITY = 10;
//空数组,无参构造函数时默认为空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//保存ArrayList元素的数组。当第一个元素插入时,任何空的ArrayList会扩大到初始容量
private transient Object[] elementData;
//实际存储的元素个数
private int size;

构造方法

ArrayList提供了三种方式的构造器,可以构造一个默认初始容量为10的空列表、构造一个指定初始容量的空列表以及构造一个包含指定collection的元素的列表,这些元素按照该collection的迭代器返回它们的顺序排列。
public ArrayList() {      this(10);  }    public ArrayList(int initialCapacity) {      super();      if (initialCapacity < 0)          throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);      this.elementData = new Object[initialCapacity];  }    public ArrayList(Collection<? extends E> c) {      elementData = c.toArray();      size = elementData.length;      // c.toArray might (incorrectly) not return Object[] (see 6260652)      if (elementData.getClass() != Object[].class)          elementData = Arrays.copyOf(elementData, size, Object[].class);  } 

存储

ArrayListt提供了set(int index,E element)、add(E e)、add(int index,E element)、addALL(Collection<? extends E> c)、addAll(int index,Collection<? extends E> c)这些添加元素的方法。
//用指定的元素替代此列表中指定位置上的元素,并返回以前位于该位置上的元素
public E set(int index,E element){
RangeCheck(index);
E oldValue = (E) elementData[index];
elementData[index] = element;
return oldValue;

}
//将指定的元素添加此列表的尾部
public boolean add(E e){
   ensureCapacity(size + 1);
   elemntData[size++] =e;
   return true;

}
读取
public E get(int index){
    RangeCheck(index);
    return (E) elementData[index];
}

删除
ArrayList提供了根据下标或者指定对象两种方式的删除功能。如下:
//移除此列表中指定位置上的元素
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;
 return oldValue;
}
ArrayList的最佳使用建议

ArrayList内部封装一个Object类型的数组,从一般的意义来说,和数组没有本质的差别,甚至到实际元素的大小,当动态数组元素确定不再添加的时候,可以调用这个方法释放空余的内存。
ToArray方法
这个方法把ArrayList的元素Copy到一个新的数组中
ArrayList与数组转换
第一种方法:
ArrayList List = new ArrayList(); 
List.Add(1); 
List.Add(2); 
List.Add(3);
Int32[] values = (Int32[])List.ToArray(typeof(Int32));
第二种方法:
ArrayList List = new ArrayList(); 
List.Add(1); 
List.Add(2); 
List.Add(3);
Int32[] values = new Int32[List.Count]; 
List.CopyTo(values);
上面介绍两种从ArrayList转换到数组的方法

ArrayList List = new ArrayList();
List.add("string");
List.add(1);
//往数组中添加不同类型的元素
object[] values = List.ToArray(typeof(object));//正确
string values = (string[])List.ToArray(typeof(string));//错误
和数组不一样,因为可以转换为Object数组,所以往ArrayList里面添加不同类型的元素是不会出错的,但是当调用ArrayList方法的时候,要么传递所有元素可以正确转型的类型或者Object类型,否则将会抛出无法类型的异常

ArrayList最佳使用

1.ArrayList内部封装了一个Object类型的数组,从一般的意义来说,它和数组没有本质的差别,甚至于ArrayList的许多方法,如Index,IndexOf,Contains,sort等都是在内部数组的基础上直接调用Array的对应方法。
2.内部的Object类型的影响
对于一般的引用类型来说,这部分的影响不是很大,但是对于值类型来说,往ArrayList里面添加和修改元素,都会引起装箱和拆箱的操作,频繁的操作可能会影响一部分效率,但是恰恰多数的应用都是使用值类型的数组,消除这个影响是没有办法,除非不用它
3.数组扩容

ArrayList类实现了List接口,由ArrayList类实现的List集合采用数组结构保存对象,数组结构的优点是便于对集合进行快速的随机访问,如果经常需要根据索引位置访问集合中的对象,使用ArrayList类实现的List集合的效率好。数组的缺点是向索引位置插入对象和删除指定索引位置对象的速度较慢。
总结:
LinkedList比较
实现:ArrayList基于数组实现,LinkedList基于链表实现
查询:ArrayList速度更快,因为随机访问,而LinkedList要遍历链表元素查询。
插入,删除:ArrayList要移动数据,缓慢,而LinkedList快速
Vector比较
扩容:ArrayList扩容时1.5倍容量,Vector为1倍
线程安全:ArrayList非线程安全;Vector线程安全,需要更大的系统开销。



原创粉丝点击