数组和数组列表都有一个很大的缺陷---从数组的中间位置删除一个元素要很大的代价:数组中处于被删除元素之后的所有元素都要向数组的前端移动,在数组中插入一个元素也是如此。
链表可以完美解决这个问题。数组在连续的存储位置上存放对象引用,但链表将每个对象存放在独立的结点中,每个结点还存放着序列中下个结点的引用,Java中所有链表都是双向连接-即每个结点还存放着指向前驱结点的引用。
链表是一个有序集合,每个对象位置很重要,LinkedList.add方法将对象添加到链表的尾部。但是在程序中常需要将元素添加到链表的中间。迭代器就是描述集合中位置的,所以依赖于位置的add方法由迭代器负责。
迭代器的add方法如果多次调用,将按照提供的次序把元素添加到链表中,被依次添加到迭代器当前位置之前。
当用一个刚刚由Iterator方法返回,并且指向链表表头的迭代器调用add操作时,新添加的元素将变成链表的新表头,当迭代器越过链表的最后一个元素时(hasNext返回false),添加的元素将变成链表的新表尾。
迭代器的set方法用一个新的元素取代调用next或previous返回的上一个元素。
ListIterator<String>iter=list.listIterator();
String oldValue=iter.next();
iter.set(newValue);
可以使用ListIterator类从前后两个方向遍历链表中的元素,并可以添加删除元素
链表不支持快速地随机访问,如果要查看链表的第n个元素,就必须从头开始,越过n-1个元素。
LinkedList类提供了一个用来访问某个特定元素的get方法:--效率并不高
get方法优化:如果索引大于1/2size()将从列表的尾部开始搜索元素
LinkedList<> list=new LinkedList<>();
String obj=list.get(n);
效率及其低的随机访问方法:每次查找一个元素都要从列表的头部重新开始搜索。
for(int i=0;i<list.size();i++){
do something with list.get(i)
}
链表迭代器有一个方法可以告之当前位置的索引。
Java迭代器返回俩个元素之间的位置,所以可以同时产生俩个索引:
nextIndex返回下一次调用next方法时返回元素的整数索引;
previousIndex方法返回下一次调用此方法时返回元素的整数索引这个索引的值比nextIndex方法返回的索引值小1;这两个方法效率非常高。
建议避免使用以整数索引表示链表中位值的所有方法。如果需要对集合进行随机访问,就使用数组或ArrayList,而不使用链表
下面的程序创建了俩个链表,将两个链表合并,然后从第二个链表中每间隔一个元素删除一个元素
当用一个刚刚由Iterator方法返回,并且指向链表表头的迭代器调用add操作时,新添加的元素将变成链表的新表头,当迭代器越过链表的最后一个元素时(hasNext返回false),添加的元素将变成链表的新表尾。
迭代器的remove操作将删除调用next之后迭代器左侧的元素
合并过程:
|ACE |BDFG
A|CE |BDFG
AB|CE B|DFG
ABCD|E BD|FG
ABCDEF| BDF|G
ABCDEFG|
删除过程:
|BDFG 第一次while
B|DFG --第一个next()
BD|FG --第二个next()
B|FG --remove操作
B|FG 第二次while
BF|G --第一个next()
BFG| --第二个next()
BF| remove操作
package com.sust.advanced;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class LinkedList {
public static void main(String[] args) {
List<String> a=new java.util.LinkedList<>();
a.add("A");
a.add("C");
a.add("E");
List<String> b=new java.util.LinkedList<>();
b.add("B");
b.add("D");
b.add("F");
b.add("G");
ListIterator<String> aIter=a.listIterator();//LinkedList类的listIterator方法返回一个实现了ListIterator接口的迭代器对象
Iterator<String> bIter=b.iterator();
while(bIter.hasNext()){ //将集合b的元素插入到集合a中 实现合并
if(aIter.hasNext())aIter.next();
aIter.add(bIter.next());
}
System.out.println(a);
bIter=b.iterator();
while(bIter.hasNext()){
bIter.next();
if(bIter.hasNext()){
bIter.next();
bIter.remove();
}
}
System.out.println(b);
a.removeAll(b);
System.out.println(a);
}
}
运行结果: