使用链表实现的List集合,LinkedList是基于双向链表实现的,实现所有可选的列表操作,并允许所有元素(包括null)。注意LinkedList实现不是同步的,所以如果需要在多线程中使用它,则它必须在外部进行同步。
LinkedList相当于链式存储,它是通过节点直接彼此连接来实现的。每一个节点都包含前一个节点的引用,后一个节点的引用和节点存储的值。当一个新节点插入时,只需要修改其中保持先后关系的节点的引用即可,当删除记录时也一样。具有以下特点:
1.操作其中对象的速度快,只需要改变连接,新的节点可以在内存中的任何地方。
2.不能随即访问,虽然存在get()方法,但是这个方法是通过遍历接点来定位的,所以速度慢。
2.LinkedList源码分析
2.1.源码
<strong>public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, Serializable {
public LinkedList() {
throw new RuntimeException("Stub!");
}
public LinkedList(Collection<? extends E> c) {
throw new RuntimeException("Stub!");
}
public E getFirst() {
throw new RuntimeException("Stub!");
}
public E getLast() {
throw new RuntimeException("Stub!");
}
public E removeFirst() {
throw new RuntimeException("Stub!");
}
public E removeLast() {
throw new RuntimeException("Stub!");
}
public void addFirst(E e) {
throw new RuntimeException("Stub!");
}
public void addLast(E e) {
throw new RuntimeException("Stub!");
}
public boolean contains(Object o) {
throw new RuntimeException("Stub!");
}
public int size() {
throw new RuntimeException("Stub!");
}
public boolean add(E e) {
throw new RuntimeException("Stub!");
}
public boolean remove(Object o) {
throw new RuntimeException("Stub!");
}
public boolean addAll(Collection<? extends E> c) {
throw new RuntimeException("Stub!");
}
public boolean addAll(int index, Collection<? extends E> c) {
throw new RuntimeException("Stub!");
}
public void clear() {
throw new RuntimeException("Stub!");
}
public E get(int index) {
throw new RuntimeException("Stub!");
}
public E set(int index, E element) {
throw new RuntimeException("Stub!");
}
public void add(int index, E element) {
throw new RuntimeException("Stub!");
}
public E remove(int index) {
throw new RuntimeException("Stub!");
}
public int indexOf(Object o) {
throw new RuntimeException("Stub!");
}
public int lastIndexOf(Object o) {
throw new RuntimeException("Stub!");
}
public E peek() {
throw new RuntimeException("Stub!");
}
public E element() {
throw new RuntimeException("Stub!");
}
public E poll() {
throw new RuntimeException("Stub!");
}
public E remove() {
throw new RuntimeException("Stub!");
}
public boolean offer(E e) {
throw new RuntimeException("Stub!");
}
public boolean offerFirst(E e) {
throw new RuntimeException("Stub!");
}
public boolean offerLast(E e) {
throw new RuntimeException("Stub!");
}
public E peekFirst() {
throw new RuntimeException("Stub!");
}
public E peekLast() {
throw new RuntimeException("Stub!");
}
public E pollFirst() {
throw new RuntimeException("Stub!");
}
public E pollLast() {
throw new RuntimeException("Stub!");
}
public void push(E e) {
throw new RuntimeException("Stub!");
}
public E pop() {
throw new RuntimeException("Stub!");
}
public boolean removeFirstOccurrence(Object o) {
throw new RuntimeException("Stub!");
}
public boolean removeLastOccurrence(Object o) {
throw new RuntimeException("Stub!");
}
public ListIterator<E> listIterator(int index) {
throw new RuntimeException("Stub!");
}
public Iterator<E> descendingIterator() {
throw new RuntimeException("Stub!");
}
public Object clone() {
throw new RuntimeException("Stub!");
}
public Object[] toArray() {
throw new RuntimeException("Stub!");
}
public <T> T[] toArray(T[] a) {
throw new RuntimeException("Stub!");
}
public Spliterator<E> spliterator() {
throw new RuntimeException("Stub!");
}
}</strong>
源码解析:
2.1.1.以上可知LinkedList继承AbstractSequentialList,AbstractList此类提供了 List 接口的骨干实现,从而最大限度地减少了实现受“连续访问”数据存储(如链接列表)支持的此接口所需的工作。对于随机访问数据(如数组),应该优先使用AbstractList,而不是先使用此类(百度百科)。实现了List,Deque双端队列。是一种具有队列和栈的性质的数据结构。实现了Cloneable、序列化Serializable。
2.1.2.属性
transient int size = 0;//大小等于0。
transient Node<E> first;//指向第一个节点。
transient Node<E> last;//指向最后一个节点。
private static final long serialVersionUID = 876323262645176354L;//序列号
2.1.3.构造方法
LinkedList有两个构造函数
public LinkedList():构造一个空的列表,里面什么都没有做。
public LinkedList(Collection<? extends E> c):构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序。
3.LinkedList常用方法
3.1.add(E e):向集合中添加一个元素
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");</strong>
3.2.add(int index, E element):向集合index位置处添加一个元素
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add(0,"张三");</strong>
3.3.addAll(Collection<? extends E> c):将某集合全部添加到另外一集合
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.add("刘六");
linkedList.add("王二麻子");
LinkedList<String> alllinkedList=new LinkedList<String>();
alllinkedList.addAll(linkedList);</strong>
3.4.addAll(int index, Collection<? extends E> c):将某集合全部添加到另外一集合的index位置处
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.add("刘六");
linkedList.add("王二麻子");
LinkedList<String> alllinkedList=new LinkedList<String>();
alllinkedList.addAll(2,linkedList);</strong>
3.5.set(int index, E element):修改index位置对应的Object
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.set(0,"李四");</strong>
3.6.remove(int index):移除此列表中指定位置上的元素。
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.remove(0);</strong>
3.7.remove(Object o):如果存在移除此列表中首次出现的指定元素。
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.remove("张三");</strong>
3.8.remove():删除第一个元素。
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.add("刘六");
linkedList.add("王二麻子");
String result=linkedList.remove();
Log.d("TAG","result----:"+result);
Iterator<String> iterator=linkedList.iterator();
while (iterator.hasNext()){
Log.d("TAG",iterator.next()+"");
}</strong>
<strong>result----:张三
*********************遍历集合***************************
李四
王五
刘六
王二麻子</strong>
3.9.get(int index)方法:获取index位置对应的Object
<strong>LinkedList<String> linkedList=new LinkedList<String>();
String s=linkedList.get(0);</strong>
3.10..size()方法:集合长度
<strong>LinkedList<String> linkedList=new LinkedList<String>();
int num=linkedList.size();</strong>
3.11.isEmpty():集合是否为空
<strong>LinkedList<String> linkedList=new LinkedList<String>();
boolean b=linkedList.isEmpty();</strong>
3.12.contains(Object o):集合是否包含o
<strong>LinkedList<String> linkedList=new LinkedList<String>();
boolean b=linkedList.contains("张三");</strong>
3.13.indexOf(Object o):集合中第一次出现o的位置
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.add("张三");
linkedList.add("刘六");
linkedList.add("王二麻子");
linkedList.add("张三");
int a=linkedList.indexOf("张三");
int b=linkedList.indexOf("刘六");
int c=linkedList.indexOf("222");
Log.d("TAG","a----:"+a);
Log.d("TAG","b----:"+b);
Log.d("TAG","c----:"+c);</strong>
<strong>a----:0
b----:4
c----:-1</strong>
3.14.lastIndexOf(Object o):集合中最后一次出现o的位置
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.add("张三");
linkedList.add("刘六");
linkedList.add("王二麻子");
linkedList.add("张三");
int d=linkedList.lastIndexOf("张三");
int e=linkedList.lastIndexOf("刘六");
int f=linkedList.lastIndexOf("222");
Log.d("TAG","d----:"+d);
Log.d("TAG","e----:"+e);
Log.d("TAG","f----:"+f);</strong>
<strong>d----:6
e----:4
f----:-1</strong>
3.15.clear():清空集合中的所有元素
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.add("张三");
linkedList.add("刘六");
linkedList.add("王二麻子");
linkedList.add("张三");
linkedList.clear();
Log.d("TAG","*********************遍历集合***************************");
Iterator<String> iterator=linkedList.iterator();
while (iterator.hasNext()){
Log.d("TAG",iterator.next()+"");
}</strong>
<strong>*********************遍历集合***************************</strong>
3.16.addFirst(E e):向集合头部添加元素
<strong> LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.addFirst("First");
Log.d("TAG","*********************遍历集合***************************");
Iterator<String> iterator=linkedList.iterator();
while (iterator.hasNext()){
Log.d("TAG",iterator.next()+"");
}
</strong>
<strong>*********************遍历集合***************************
First
张三
李四
王五
</strong>
3.17.addLast(E e):向集合尾部添加元素
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.addLast("Last");
Log.d("TAG","*********************遍历集合***************************");
Iterator<String> iterator=linkedList.iterator();
while (iterator.hasNext()){
Log.d("TAG",iterator.next()+"");
}</strong>
<strong>*********************遍历集合***************************
张三
李四
王五
Last
</strong>
3.18.getFirst():返回集合的第一个元素
<strong> LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
String s=linkedList.getFirst();
Log.d("TAG","s----:"+s);</strong>
<strong>s----:张三</strong>
3.19.getLast():返回集合最后一个元素
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
String s=linkedList.getLast();
Log.d("TAG","s----:"+s);</strong>
<strong>s----:王五</strong>
4.LinkedList删除数据
4.1.remove(int inedex)删除
代码:
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.add("刘六");
linkedList.add("王二麻子");
/**
* 删除“王五”后立刻取出“刘六”
* */
//方法1.remove(int index)
linkedList.remove(2);
String result=linkedList.get(3);
Log.d("TAG","3位置上对应的结果----:"+result);
Log.d("TAG","删除“王五”后立刻取出“刘六”遍历集合");
Iterator<String> iterator=linkedList.iterator();
while (iterator.hasNext()){
Log.d("TAG",iterator.next()+"");
}
</strong>
结果:
<strong>3位置上对应的结果----:王二麻子
删除“王五”后立刻取出“刘六”遍历集合
张三
李四
刘六
王二麻子</strong>
4.2.remove(Object o)方法
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.add("刘六");
linkedList.add("王二麻子");
/**
* 删除“王五”后立刻取出“刘六”
* */
//方法2.remove(Object o)
linkedList.remove("王五");
String result=linkedList.get(3);
Log.d("TAG","3位置上对应的结果----:"+result);
Log.d("TAG","删除“王五”后立刻取出“刘六”遍历集合");
Iterator<String> iterator=linkedList.iterator();
while (iterator.hasNext()){
Log.d("TAG",iterator.next()+"");
}</strong>
<strong>3位置上对应的结果----:王二麻子
删除“王五”后立刻取出“刘六”遍历集合
张三
李四
刘六
王二麻子</strong>
4.3.Iterator.remove()方法删除
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.add("刘六");
linkedList.add("王二麻子");
/**
* 删除“王五”后立刻取出“刘六”
* */
//方法3.Iterator.remove()
Iterator iter = linkedList.iterator();
while (iter.hasNext()) {
if (iter.next().equals("王五")) {
iter.remove();
}
}
String result=linkedList.get(3);
Log.d("TAG","3位置上对应的结果----:"+result);
Log.d("TAG","删除“王五”后立刻取出“刘六”遍历集合");
Iterator<String> iterator=linkedList.iterator();
while (iterator.hasNext()){
Log.d("TAG",iterator.next()+"");
}</strong>
<strong>3位置上对应的结果----:王二麻子
删除“王五”后立刻取出“刘六”遍历集合
张三
李四
刘六
王二麻子
</strong>
集合的删除 一般情况下使用remove(int inedex),remove(Object o)或是Iterator.remove()方法都可以。(比如上述删除某个已知的元素(要删除的元素位置和值都确定且只删除一个))。
而要遍历集合删除循环删除时建议使用迭代器的删除即Iterator.remove()方法删除。
举例
代码1:
<strong>LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.add("刘六");
linkedList.add("王二麻子");
int num=linkedList.size();
for(int i=0;i<num;i++){
String s=linkedList.get(i);
if("李四".equals(s)){
linkedList.remove("李四");
}
}
Log.d("TAG","*********************遍历集合***************************");
Iterator<String> iterator=linkedList.iterator();
while (iterator.hasNext()){
Log.d("TAG",iterator.next()+"");
}</strong>
结果1:报错(数组下标越界)
代码2:
<strong> LinkedList<String> linkedList=new LinkedList<String>();
linkedList.add("张三");
linkedList.add("李四");
linkedList.add("王五");
linkedList.add("刘六");
linkedList.add("王二麻子");
Iterator iter = linkedList.iterator();
while (iter.hasNext()) {
if (iter.next().equals("李四")) {
iter.remove();
}
}
Log.d("TAG","*********************遍历集合***************************");
Iterator<String> iterator=linkedList.iterator();
while (iterator.hasNext()){
Log.d("TAG",iterator.next()+"");
}
</strong>
<strong>*********************遍历集合***************************
张三
王五
刘六
王二麻子</strong>
6.LinkedList总结
因为它是基于双向链表实现的,主要有如下特点:
1、插入、删除比较快,每一个节点都包含前一个节点的引用,后一个节点的引用和节点存储的值。当一个新节点插入时,只需要修改其中保持先后关系的节点的引用即可,当删除记录时也一样。
2、可以重复插入数据、可以插入null。
3、查找比较慢,虽然存在get()方法,但是这个方法是通过遍历接点来定位的,所以速度慢。