List接口的几个实现类
回顾List接口
- List接口有很多实现类,通常我们使用其中的这三个:
- ArrayList
- LinkedList
- Vector
下面附上List接口和其他接口以及其他类包括Collection接口的继承关系图:
1.ArrayList
1)特点
ArrayList子类是List接口中最常用的子类
特点:
底层数据结构是数组,查询快,增删慢
数组长度可变
线程不安全,效率高
ArrayList中要适当覆写.equals方法和.tostring方法
2)构造方法
构造方法:
ArrayList()
构造一个初始容量为 10 的空列表
ArrayList(int initialCapacity) 避免频繁扩容
指定 ArrayList 的初始容量
ArrayList(Collection c)
构造一个包含指定 collection 的元素的列表
3)API
API:
void ensureCapacity(int minCapacity) 避免频繁扩容,保证ArrayList至少能容纳minCapacity个元素
void trimToSize() 缩小底层数组的大小,达到和实际存储元素的个数一致。
建议:当ArrayList的元素不再变化的时候,再使用这个方法。
2.Vector
1)特点
1.在JDK1.0时就已提供Vector类,同时由于其提供的较早,此类被大量使用.但是到了JDK1.2由于类集框架的引入,
对于整个集合的操作就有了新的标准,为了继续保留Vector类,就让其多实现了List接口.
2.底层数据结构是数组,查询快,增删慢
3.数组长度可变
4.线程安全,效率低
与ArrayList最大的区别在于此类中部分方法使用synchronized关键字申明(同步操作)
2)API
Vector 特有的API :
public void addElement(E obj)
public E elementAt(int index)
public Enumeration elements()
void addElement(E obj) --> boolean add(E e)将指定元素添加到此向量的末尾。
void copyInto(Object[] anArray) --> Object[] toArray()
E elementAt(int index) --> E get(int index)
void insertElementAt(E obj, int index) --> void add(int index, E e)
void removeAllElements() --> void clear()
boolean removeElement(Object obj) --> void remove(Object obj)
void removeElementAt(int index) --> void remove(int index)
void setElementAt(E obj, int index) --> E set(int index, E e)
int capacity()实际能容纳的元素
E firstElement()第一个元素
E lastElement()最后一个元素
int indexOf(Object o, int index)从第index索引开始找,没有返回-1
int lastIndexOf(Object o, int index)
Enumeration<E> elements() --> Iterator iterator()
Enumeration接口 --> Iterator接口
boolean hasMoreElements() --> boolean hasNext()
E nextElement() --> E next()
3.LinkedList
1)特点
1.底层是链表, 增删快, 查找慢
2.不同步, 线程不安全, 效率高
2)构造方法和API
构造方法:
LinkedList()
构造一个空列表。
LinkedList(Collection<? extends E> c)
构造一个包含指定 collection 中的元素的列表,这些元素按其 collection 的迭代器返回的顺序排列。
LinkedList 特有的API:
public void addFirst(E e)及addLast(E e)
public E getFirst()及getLast()
public E removeFirst()及public E removeLast()
3)实现其他接口
LinkedList类 不仅实现了接口 List, 还实现了接口Deque
通过Deque接口可以用来实现栈
Deque接口实现的方法:
第一个元素(头部) 最后一个元素(尾部)
抛出异常 特殊值 抛出异常 特殊值
插入 addFirst(e) offerFirst(e) addLast(e) offerLast(e)
移除 removeFirst() pollFirst() removeLast() pollLast()
检查 getFirst() peekFirst() getLast() peekLast()
操作栈的API:(一般通过Deque接口进行栈操作,而不用Stack类)
void push(E e)
E pop()
E peek()
boolean isEmpty()
4)迭代器
ListIterator<E> listIterator(int index)
返回此列表中的元素的列表迭代器(按适当顺序),从列表中指定位置开始
Iterator<E> descendingIterator()
返回以逆向顺序在此双端队列的元素上进行迭代的迭代器
boolean removeFirstOccurrence(Object o)
从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表时)。
boolean removeLastOccurrence(Object o)
从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表时)。
4.练习题
/*
1.去重
示例:
输入: ['A', 'B', 'C', 'A']
输出: ['A', 'B', 'C']
思路1:
a. 新建一个List
b. 遍历原集合,拿到每一个元素
如果在新集合中已经存在, 不添加
如果在新集合中不存在, 添加
思路2:
拿到第一个元素, 然后删除后面所有与第一个元素相等的元素
拿到第二个元素, 然后删除后面所有与第二个元素相等的元素
...
*/
public class Ex1 {
/*
时间复杂度:O(n^2)
空间复杂度:O(n)
*/
/* public static List removeDuplicated(List list) {
List result = new ArrayList();
for(Iterator it = list.iterator(); it.hasNext(); ) {
Object obj = it.next();
if (!result.contains(obj)) result.add(obj);
}
return result;
}*/
/*
时间复杂度:O(n^3)
空间复杂度:O(1)
*/
public static void removeDuplicated(List list) {
// int size = list.size();
for(int i = 0; i < list.size(); i++) {
Object obj = list.get(i);
for (int j = i + 1; j < list.size(); j++) {
if (obj.equals(list.get(j))) {
list.remove(j);
j--; // caution! 需要回退一步
}
}
}
}
public static void main(String[] args) {
List list = new ArrayList();
list.add('A');
list.add('B');
list.add('C');
list.add('A');
list.add('A');
list.add('A');
list.add('A');
removeDuplicated(list);
System.out.println(list);
}
}