Java的List接口

List接口简介

List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。

List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。

JDK API中List接口的实现类常用的有:ArrayListLinkedListVector

List 集合里添加了一些根据索引来操作集合元素的方法:

add(int index, Object ele)

boolean addAll(int index, Collection eles)

Object get(int index)

int indexOf(Object obj)

int lastIndexOf(Object obj)

Object remove(int index)

Object set(int index, Object ele)

List subList(int fromIndex, int toIndex)

 

List实现类之一:ArrayList

ArrayList 是 List 接口的典型实现类,本质上,ArrayList是对象引用的一个变长数组。

ArrayList 是 List 接口的可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。

ArrayList 是线程不安全的,而 Vector 是线程安全的,即使为保证 List 集合线程安全,也不推荐使用Vector。

Arrays.asList(…) 方法返回的 List 集合既不是 ArrayList 实例,也不是 Vector 实例。 Arrays.asList(…)返回值是一个固定长度的 List 集合。

 

ArrayList的存取实现

存储:

ArrayList 提供了 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);

elementData[size++] = e;

return true;

}

// 将指定的元素插入此列表中的指定位置。

// 如果当前位置有元素,则向右移动当前位于该位置的元素以及所有后续元素(将其索引加 1)。

public void add(int index, E element) {

if (index > size || index < 0)

          throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);

// 如果数组长度不足,将进行扩容

ensureCapacity(size+1); // Increments modCount!!

// elementData 中从 Index 位置开始、长度为 size-index 的元素,

// 拷贝到从下标为 index+1 位置开始的新的 elementData 数组中。

// 即将当前位于该位置的元素以及所有后续元素右移一个位置。

System.arraycopy(elementData, index, elementData, index + 1, size - index);

elementData[index] = element;

size++;

}

// 按照指定collection的迭代器所返回的元素顺序,将该collection中的所有元素添加到此列表的尾部
public boolean addAll(Collection<? extends E> c) {

Object[] a = c.toArray();

int numNew = a.length;

// 如果数组长度不足,将进行扩容

ensureCapacity(size + numNew); // Increments modCount

System.arraycopy(a, 0, elementData, size, numNew);

size += numNew;

return numNew != 0;

}

// 指定的位置开始,将指定 collection 中的所有元素插入到此列表中。
public boolean addAll(int index, Collection<? extends E> c) {

if (index > size || index < 0)

         throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);

Object[] a = c.toArray();

int numNew = a.length;

ensureCapacity(size + numNew); // Increments modCount

int numMoved = size - index;

if (numMoved > 0)

         System.arraycopy(elementData, index, elementData, index + numNew, numMoved);

System.arraycopy(a, 0, elementData, index, numNew);

size += numNew;

return numNew != 0;

}

读取:

// 返回此列表中指定位置上的元素。

public E get(int index) {

RangeCheck(index);

return (E) elementData[index];

}

 

List实现类之二:LinkedList

对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高

新增方法:

void addFirst(Object obj)

void addLast(Object obj)

Object getFirst()

Object getLast()

Object removeFirst()

Object removeLast()

 

List实现类之三:Vector

Vector是一个古老的集合,JDK1.0就有了。大多数操作与ArrayList相同,区别之处在于Vector是线程安全的。

在各种list中,最好把ArrayList作为缺省选择。当插入、删除频繁时,使用LinkedList;Vector总是比ArrayList慢,所以尽量避免使用。

新增方法:

void addElement(Object obj)

void insertElementAt(Object obj,int index)

void setElementAt(Object obj,int index)

void removeElement(Object obj)

void removeAllElements()

 

ArrayList与Vector的区别:

比较点

ArrayList

Vector

推出时间

JDK1.2之后推出的,属于新的操作类

JDK1.0时推出的,属于旧的操作类

性能

采用异步处理方式,性能更高

采用同步处理方式,性能较低

线程安全

属于非线程安全的操作类

属于线程安全的操作类

输出

只能使用Iterator、foreach输出

可以使用Iterator、foreach、Enumeration输出

 

数组(Array)和列表(ArrayList)有什么区别?

1)Array可以包含基本类型和对象类型(引用类型), ArrayList只能包含对象类型。

2)Array 大小是固定的, ArrayList 的大小是动态变化的。

3)ArrayList 提供了更多的方法和特性,比如: addAll(), removeAll(), iterator()等等。

 

什么时候应该使用 Array 而不是 ArrayList?

对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。

 

ArrayList 和 LinkedList 有什么区别?

1)ArrayList 是基于索引的数据接口,它的底层是数组。它可以以 O(1)时间复杂度对元素进行随机访问。与此对应, LinkedList 是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是 O(n)。

2)相对于 ArrayList, LinkedList 的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。

3)LinkedList 比 ArrayList 更占内存,因为 LinkedList 为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。

 

猜你喜欢

转载自blog.csdn.net/lxxiang1/article/details/81277255