在这里,我们将介绍List接口和实现了这个接口的LinkList类。List接口用于描述一个有序集合,并且集合中每个元素的位置十分重要。有两种访问元素的协议:一种是迭代器,另一种是get和set方法随机地访问每一个元素。后者不适用于链表,但是对数组却很有用。集合类库提供了一种大家都很熟悉的ArrayList类,这个类也实现了List接口。ArrayList封装了一个动态再分配的对象数组。
但是我们的主要关注点依旧在于链表的使用。
在之前,有很多示例已经使用了数组以及动态的ArrayList类。然而,数组和数组列表都有一个重大的缺陷,这就是从数组的中间位置删除一个元素要付出很大的代价,其原因是数组中处于被删除元素之后的所有元素都要向前端移动。在数组中间的位置插入一个元素也是如此。
这个时候,我们就引入了链表:在Java设计语言中,所有链表实际上都是双向链接的,即数据结构中的双向链表。
下面我们来看一看涉及链表的重要方法:
1.Iterator.add()
在下面的代码示例中,先添加三个元素,然后再将第二个元素删除:
List<String>staff=new LinkedList<>();
staff.add("Amy");
staff.add("Bob");
staff.add("Carl");
Iterator iter=staff.iterator();
String first=iter.next();
String second=iter.next();
iter.remove();//如果想要删除指定位置上的元素,我们仍然需要去越过它,这里是删除了第二个元素,即“Bob”
2.ListIterator.add()
集合类库提供了子接口ListIterator,其中包含方法add:
interface Listerator<E> extends Iterator<E>{
void add(E element);
...
}
作为比照,我们将Iterator.add()列出:
public interface Collection<E>{
boolean add(E element);
Iterator<E> iterator();//iterator是迭代器的意思
}
可以看到,ListIterator.add()不返回boolean类型的值,它假定添加操作总会改变链表。另外,ListIterator接口还有两个方法,可以用来反向遍历链表:
E previous()
boolean hasPrevious()
与next方法一样,previous方法返回越过的对象。
另外,LinkedList类的listIterator方法返回了一个实现了ListIterator接口的迭代器对象。
ListIterator<E> listIterator();
与之相对的:
Iterator<E> iterator();
add方法在迭代器位置之前添加一个新对象。
List<String> staff=new LinkedList<>();
staff.add("Amy");
staff.add("Bob");
staff.add("Carl");
ListIterator<String> iter=staff.listIterator();
iter.next();
iter.add("Juliet");
3.ListIterator.set()
set方法用一个新元素取代调用next或previous方法返回的元素:
下面的代码将用一个新值取代链表的第一个元素:
ListIterator<String>iter=list.listIterator();
String oldValue=iter.next();
iter.set(newValue);
最后说一下:为了避免多个迭代器造成的混乱,可以根据需要给容器附加许多的迭代器,但是这些迭代器只能读取列表。另外再附加一个既能读又能写的迭代器。
4.示例程序
示例程序使用的就是链表,它简单地创建了两个链表,将它们合并在一起,然后从第二个链表中每间隔一个元素删除一个元素,最后测试了removeAll方法。
package Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
public class LinkedListTest {
public static void main(String[] args){
List<String> a=new LinkedList<>();
a.add("Amy");
a.add("Carl");
a.add("Erica");
List<String> b=new LinkedList<>();
b.add("Bob");
b.add("Doug");
b.add("Frances");
b.add("Gloria");
ListIterator <String> aIter=a.listIterator();
Iterator <String> bIter=b.iterator();
while(bIter.hasNext()){
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);
}
}