1. 概述
List 接口 是 Collection 和 IterAble 的一个子接口,List 集合中的 元素是有顺序的,并且元素可以重复。实现的List接口 的容器类有 ArrayList 类, LinkedList 类, Vector 类。
ArrayList 类,实现一个 可变大小的 数组 , 可以像链表一样被访问,他是以数组的方式实现的,允许快速随机存取,也就是说ArrayList 适用于访问比较多,插入删除比较少的情况。未实现同步,线程不安全。
LinkedList类 ,允许出现为 null 的元素 ,LinkedList 实现了一个链表。可以对集合的首部和尾部进行插入和删除操作。相较于 ArrayList ,LinkedList 插入和删除性能好,ArrayList 查询性能好,也就是说 LinkedList 适用于访问比较少,插入删除比较多的情况。未实现同步,线程不安全。
Vector 和
ArrayList 大致相同,但是 Vector 实现了同步,线程安全。如果不需要线程安全的实现,建议使用 ArrayList 代替 Vector。
Collection 还有一个子接口 Set , Set 是无序的,并且元素不可以重复。
接下来去学习一下 ArrayList 类, Vector 类, LinkedList 类。
2. ArrayList 类
ArrayList 类实现一个 可变大小的 数组 , 可以像链表一样被访问,他是以数组的方式实现的,允许快速随机存取。ArrayList 类 源码 中是这样存储的 。此实现不同步。
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
接下来列出ArrayList 的 一些方法 ,如果想要学习所有的方法,可以看官方文档 ,Java8 :传送。Java9:传送。
修饰符和返回类型 |
方法名和参数 |
方法描述 |
void |
将指定元素插入此列表中的指定位置 |
|
boolean |
将指定的元素追加到此列表的末尾 |
|
abstract E |
get(int index) |
返回此列表中指定位置的元素。 |
int |
返回此列表中第一次出现的指定元素的下标,如果此列表不包含该元素,则返回-1。 |
|
iterator() |
以适当的顺序返回此列表中元素的迭代器。 |
|
int |
返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回-1。 |
|
remove(int index) |
删除此列表中指定位置的元素。 |
|
使用指定的元素替换此列表中指定位置的元素 |
||
subList(int fromIndex, int toIndex) |
返回一个新的集合,新集合元素是从原集合的 |
用一个程序来试一下上面的方法。
package list;
import sun.plugin.javascript.navig.LinkArray;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 学习ArrayList
*/
public class myArrayListStudy {
public static void main(String args[]) {
// 创建列表
List<Integer> arrayList = new ArrayList();
// 向列表中追加元素,元素下标从 0 开始
arrayList.add(1);
arrayList.add(5);
arrayList.add(3);
// 获得下标为 1 的元素,集合里面的元素为: 1 5 3
System.out.println(arrayList.get(1));
// 将元素 6 插入此列表中下标为 1 的位置, 集合里面的元素为: 1 6 5 3
arrayList.add(1, 6);
// 遍历一下列表,
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
// 替换元素 3 为 6, 集合里面的元素为: 1 6 5 6
arrayList.set(3, 6);
// 返回此列表中第一次出现的 元素6 的下标 : 1
System.out.println(arrayList.indexOf(6));
// 返回此列表中最后一次出现的 元素6 的下标 : 3
System.out.println(arrayList.lastIndexOf(6));
// 删除集合下标为 3 的元素
arrayList.remove(3);
iterator = arrayList.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println("");
// 取出arrayList 下标[0,2) 的值 给 arrayList1
List<Integer> arrayList1 = arrayList.subList(0, 2);
iterator = arrayList1.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
}
}
程序运行截图:
2. LinkedList 类
LinkedList类 ,允许出现为 null 的元素 ,LinkedList 实现了一个链表。可以对集合的首部和尾部进行插入和删除操作。相较于 ArrayList ,LinkedList 插入和删除性能好,ArrayList 查询性能好,这也是链表和数组的优劣。此实现不同步。
LinkedList 的部分源码 ,实现了一个链表。
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
/**
* Pointer to first node.
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.item != null)
*/
transient Node<E> first;
/**
* Pointer to last node.
* Invariant: (first == null && last == null) ||
* (last.next == null && last.item != null)
*/
transient Node<E> last;
/**
* Constructs an empty list.
*/
public LinkedList() {
}
/** 下面的内容略 **/
}
下面列出来 LinkedList 的一些方法,如果想要学习所有的方法,可以看官方文档 ,Java8 :传送。Java9:传送。
修饰符和返回类型 |
方法名和参数 |
方法描述 |
void |
在此列表的开头插入指定的元素。 |
|
void |
将指定的元素追加到此列表的末尾。 |
|
getFirst() |
返回此列表中的第一个元素。 |
|
getLast() |
返回此列表中的最后一个元素。 |
|
从此列表中删除并返回第一个元素。 |
||
从此列表中删除并返回最后一个元素。 |
||
listIterator(int index) |
从列表中的指定位置index开始,返回此列表中元素的列表迭代器。 |
用一个程序来试一下上面的方法。
package list;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
/**
* 学习 LinkedList
*/
public class myLinkedListStudy {
public static void main(String args[]) {
// 创建列表
LinkedList<String> linkedList = new LinkedList<String>();
// 添加两个元素
linkedList.add("aaa");
linkedList.add("bbb");
linkedList.addFirst("ddd");
linkedList.addLast("ccc");
// 打印列表: ddd aaa bbb ccc
PrintLinkedList(linkedList, 0);
// 返回此列表中的第一个元素
System.out.println(linkedList.getFirst());
// 返回此列表中的最后一个元素
System.out.println(linkedList.getLast());
// 从此列表中删除并返回第一个元素
System.out.println(linkedList.removeFirst());
// 从此列表中删除并返回最后一个元素
System.out.println(linkedList.removeLast());
// 打印列表: aaa bbb
PrintLinkedList(linkedList, 0);
}
/**
* 从下标fromIndex 开始, 打印列表 temp
* @param temp: 要被打印的列表
* @param fromIndex: 开始的下标
*/
public static void PrintLinkedList(List temp, int fromIndex) {
ListIterator iterator = temp.listIterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println("");
}
}
程序运行截图如下:
3. Vector 类
Vector和
ArrayList 大致相同,但是 Vector实现了方法
同步,是线程安全的。如果不需要线程安全的实现,建议使用 ArrayList 代替 Vector
。
Vector 中的部分方法 实现了 synchronized 关键字,百度百科对synchronized 的介绍。 synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、 D等)正在用这个方法(或者该类的其他同步方法),有的话要等正在使用synchronized方法的线程B(或者C 、D)运行完这个方法后再运行此线程A,没有的话,锁定调用者,然后直接运行。它包括两种用法:synchronized 方法和 synchronized 块。
如下 , Vector 源码中
实现了 synchronized 关键字的一个方法。
public synchronized void setElementAt(E obj, int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
elementData[index] = obj;
}