1.List介绍
Java集合主要由两个体系组成。分别是Colletcion体系和Map体系,而Collection和Map是这两大体系的上层接口。List就是Collection的一个子接口,List(列表)中的元素是有序可重复的,而与它对应的Set(集)中的元素是无序不可重复的。
在Colletcion中,List集合是有序的,可对其中的每个元素的位置进行准确的控制,可以通过索引来访问元素,遍历元素。
List又主要由ArrayList和LinkedList两个实现类组成的。
1.1List方法介绍
add(E e)
将指定的元素追加到此列表的末尾(可选操作)。
add(int index, E element)
将指定的元素插入此列表中的指定位置(可选操作)。
addAll(int index, Collection<? extends E> c)
将指定集合中的所有元素插入到此列表中的指定位置(可选操作)。
clear()
从此列表中删除所有元素(可选操作)。
contains(Object o)
如果此列表包含指定的元素,则返回 true 。
containsAll(Collection<?> c)
如果此列表包含指定 集合的所有元素,则返回true。
equals(Object o)
将指定的对象与此列表进行比较以获得相等性。
get(int index)
返回此列表中指定位置的元素。
hashCode()
返回此列表的哈希码值。
indexOf(Object o)
返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。
isEmpty()
如果此列表不包含元素,则返回 true 。
ilastIndexOf(Object o)
返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。
E remove(int index)
删除该列表中指定位置的元素(可选操作)。
remove(Object o)
从列表中删除指定元素的第一个出现(如果存在)。
removeAll(Collection<?> c)
从此列表中删除包含在指定集合中的所有元素。
retainAll(Collection<?> c)
仅保留此列表中包含在指定集合中的元素 。
E set(int index, E element)
用指定的元素替换此列表中指定位置的元素。
size()
返回此列表中的元素数。
Object[] toArray()
以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组。
2.ArrayList集合
1.ArrayList是通过数组的实现对元素进行增加和动态的扩容。
2.ArrayList是Java集合框架中使用的最广泛的一个类,是一个数组队列,是线程不安全的集合。
2.1ArrayList继承了AbstractList,实现了List,RandonmAccess,Cloneable,Serializable接口
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
1.继承了AbstractList抽象类
AbstractList抽象类实现了List接口,实现了List接口中的一些通用的方法,ArryList继承了该类,拿到了一些通用的方法,然后在实现了一些自己特有的方法。
2.ArrayList实现List,得到了List集合框架基础功能。
3.ArrayList实现了RandonmAccess,支持快速随机访问。
4.ArrayList实现了Cloneable,实现了clone()方法,可以提供克隆。
源码:
public Object clone() {
try {
@SuppressWarnings("unchecked")
ArrayList<E> v = (ArrayList<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
5.实现了Serializable,指代ArrayList可以被序列化,从而方便存储货运输。
2.2ArrayList集合特点
1.容量不固定,可以动态扩容(50%)
2.有序可重复集合
3.线程是不安全的
4.插入的元素可以为null
5.利用索引位置可以快速访问
2.3ArrayList常用的方法
trimToSize
public void trimToSize()修改这个ArrayList实例的容量是列表的当前大小。 应用程序可以使用此操作来最小化ArrayList实例的存储。
ensureCapacity
public void ensureCapacity(int minCapacity)如果需要,增加此 ArrayList实例的容量,以确保它至少可以容纳最小容量参数指定的元素数。
参数
minCapacity - 所需的最小容量
size
public int size()返回此列表中的元素数
isEmpty
public boolean isEmpty()如果此列表不包含元素,则返回 true 。
contains
public boolean contains(Object o)如果此列表包含指定的元素,则返回true 。 更正式地说,返回true当且仅当此列表包含至少一个元素e这样(onull ? enull : o.equals(e))。
indexOf
public int indexOf(Object o)返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。 更正式地,返回最低指数i ,使(o==null ? get(i)==null : o.equals(get(i))) ,或-1如果没有这样的索引。
toArray
public T[] toArray(T[] a)以正确的顺序返回一个包含此列表中所有元素的数组(从第一个到最后一个元素); 返回的数组的运行时类型是指定数组的运行时类型。 如果列表适合指定的数组,则返回其中。 否则,将为指定数组的运行时类型和此列表的大小分配一个新数组。
如果列表适用于指定的数组,其余空间(即数组的列表数量多于此元素),则紧跟在集合结束后的数组中的元素设置为null 。 (这仅在调用者知道列表不包含任何空元素的情况下才能确定列表的长度。)
2.4ArrayList遍历机制(方法)
ArrayList<Integer> as = new ArrayList<Integer>(10000);
for (int i = 0; i < 10000; i++) {
as.add(i);
}
traverseByIterator(as);
traverseByIndex(as);
traverseByFor(as);
}
private static void traverseByIterator(ArrayList<Integer> as) {
long starTime = System.nanoTime();
System.out.println("迭代器遍历");
Iterator<Integer> iter1 = as.iterator();
while (iter1.hasNext()) {
iter1.next();
}
long endTime = System.nanoTime();
long duration = endTime-starTime;
System.out.println(duration+"纳秒");
}
private static void traverseByIndex(ArrayList<Integer> as) {
long starTime = System.nanoTime();
System.out.println("随机索引遍历");
for (int i = 0; i <as.size(); i++) {
as.get(i);
}
long endTime = System.nanoTime();
long duration = endTime-starTime;
System.out.println(duration+"纳秒");
}
private static void traverseByFor(ArrayList<Integer> as) {
long starTime = System.nanoTime();
System.out.println("for-each遍历");
for (Integer integer : as) {
;
}
long endTime = System.nanoTime();
long duration = endTime-starTime;
System.out.println(duration+"纳秒");
}
结果:
迭代器遍历
1285200纳秒
随机索引遍历
771900纳秒
for-each遍历
1394400纳秒
3.LinkedList集合
1,LinkedList底层通过链表来实现,随着元素的增加不断向链表的后端增加节点。
2,LinkedList是一个双向链表,每一个节点都拥有指向前后节点的引用。相比于ArrayList来说,LinkedList的随机访问效率更低。
3.1LinkedList继承了AbstractSequentialList,实现了List,Cloneable,Deque,Senrializable接口
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
1.LinkedList继承了AbstractSequentialList抽象类,是有序的顺序列表。
2.LinkedList实现了List,得到了List集合框架基础功能。
3.LinkedList实现了Cloneable,实现了clone()方法,可以提供克隆。
4.LinkedList实现了Deque,提供了双端对列插入元素,及既可以在头部添加元素,又可以在尾部添加元素。
源码
public boolean offer(E e) {
return add(e);
}
// Deque operations
/**
* 在开头插入指定元素
*
* @参数 e 要插入的元素
* @return {@code true} (as specified by {@link Deque#offerFirst})
* @since 1.6
*/
public boolean offerFirst(E e) {
addFirst(e);
return true;
}
/**
* 在结尾插入指定元素
*
* @参数 e 要插入的元素
* @return {@code true} (as specified by {@link Deque#offerLast})
* @since 1.6
*/
public boolean offerLast(E e) {
addLast(e);
return true;
}
5.LinkedList实现了Senralizable,表示被序列化,可以通过序列传输。
3.2LinkedList特点
1.可以通过双向链表实现。
2.不存在容量不足的问题。
3.实现了Deque定义了在双端队列两端访问元素的方法。
4.适合删除操作,因为删除不会发生移位。
5.维护了元素插入的顺序。
6.非线程安全集合。
3.3LinkedList常用方法
getFirst
public E getFirst()返回此列表中的第一个元素
getLast
public E getLast()返回此列表中的最后一个元素。
removeFirst
public E removeFirst()从此列表中删除并返回第一个元素。
removeLast
public E removeLast()从此列表中删除并返回最后一个元素。
addFirst
public void addFirst(E e)在该列表开头插入指定的元素。
addLast
public void addLast(E e)将指定的元素追加到此列表的末尾。
contains
public boolean contains(Object o)如果此列表包含指定的元素,则返回true 。
size
public int size()返回此列表中的元素数
remove
public boolean remove(Object o)从列表中删除指定元素的第一个出现(如果存在)。 如果此列表不包含该元素,则它将保持不变。 更正式地,删除具有最低索引i的元素,使得(o==null ? get(i)==null : o.equals(get(i))) (如果存在这样的元素)。 如果此列表包含指定的元素(或等效地,如果此列表作为调用的结果而更改),则返回true 。
3.4LinkedList遍历方法
LinkedList<Integer> list = new LinkedList<Integer>();
for (int i = 0; i < 10000; i++) {
list.add(i);
}
System.out.println("==========遍历方法=======");
traverseByIterator(list);
traverseByIndex(list);
traverseByFor(list);
}
private static void traverseByIterator(LinkedList<Integer> list) {
long starTime = System.nanoTime();
System.out.println("迭代器遍历");
Iterator<Integer> iter1 = list.iterator();
while (iter1.hasNext()) {
iter1.next();
}
long endTime = System.nanoTime();
long duration = endTime-starTime;
System.out.println(duration+"纳秒");
}
private static void traverseByIndex(LinkedList<Integer> list) {
long starTime = System.nanoTime();
System.out.println("随机索引遍历");
for (int i = 0; i <list.size(); i++) {
list.get(i);
}
long endTime = System.nanoTime();
long duration = endTime-starTime;
System.out.println(duration+"纳秒");
}
private static void traverseByFor(LinkedList<Integer> list) {
long starTime = System.nanoTime();
System.out.println("for-each遍历");
for (Integer integer : list) {
;
}
long endTime = System.nanoTime();
long duration = endTime-starTime;
System.out.println(duration+"纳秒");
}
结果:
迭代器遍历
1403700纳秒
随机索引遍历
64189100纳秒
for-each遍历
511300纳秒