LinkedList——双向链表
所有已实现的接口:
Serializable, Cloneable, Iterable, Collection, Deque, List, Queue
LinkedList作为List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。
此类实现 Deque 接口,为 add、poll 提供先进先出队列操作,以及其他堆栈和双端队列操作。也就是说,LinkedList能够作为队列操作数据。
构造方法摘要
-
LinkedList()
构造一个空列表。 -
LinkedList(Collection<? extends E> c)
构造一个包含指定 collection 中的元素的列表,这些元素按其 collection 的迭代顺序排列。
常用方法: -
boolean add(E e)
将指定元素添加到此列表的结尾。 -
void add(int index, E element)
在此列表中指定的位置插入指定的元素。 -
boolean addAll(Collection<? extends E> c)
添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序。 -
boolean addAll(int index, Collection<? extends E> c)
将指定 collection 中的所有元素从指定位置开始插入此列表。 -
boolean contains(Object o)
如果此列表包含指定元素,则返回 true。 -
E get(int index)
返回此列表中指定位置处的元素。 -
E poll()
获取并移除此列表的头(第一个元素) 即出列 -
E pop()
从此列表所表示的堆栈处弹出一个元素。即出栈 -
void push(E e)
将元素推入此列表所表示的堆栈。 -
E remove()
获取并移除此列表的头(第一个元素)。 -
E remove(int index)
移除此列表中指定位置处的元素。 -
boolean remove(Object o)
从此列表中移除首次出现的指定元素(如果存在)。 -
Object[] toArray()
返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组。 -
T[] toArray(T[] a)
返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组;返回数组的运行时类型为指定数组的类型。
下面模拟LinkedList实现MyLinkedList(单向链表实现,并且对Stack方法、Queue方法进行了模拟)
public class MyLinkedList {
private Node head = new Node();
private int size = 0;
private class Node{
Object data;
Node next;
public Node() {}
public Node(Object data) {
this.data = data;
}
}
public void add(Object obj) {
add(size, obj);
}
public void add(int index,Object obj) {
checkOutOfBoundsWhenAdd(index);
Node p = head;
Node newNode = new Node(obj);
for(int i = 0 ; i < index ; i ++)
p = p.next;
newNode.next = p.next;
p.next = newNode;
size++;
}
public Object remove(Object obj) {
Object oldelement = null;
Node node = head.next;
Node pre = head;
while(node != null)
{
if(node.data.equals(obj)) {
oldelement = node.data;
pre.next = node.next;
this.size -- ;
break;
}
pre = node;
node = node.next;
}
return oldelement;
}
public void push(Object obj) {//压栈
Node newNode = new Node(obj);
newNode.next = this.head.next;
this.head.next = newNode;
size++;
}
public Object pop() {//出栈
if(head.next == null)
throw new NoSuchElementException("Stack is Empty");
Object result = head.next.data;
head.next = head.next.next;
size --;
return result;
}
public Object set(int index,Object obj) {
checkOutOfBoundsWhenSearch(index);
Node node = head.next;
for(int i = 0 ; i < index ; i ++)
node = node.next;
Object oldelement = node.data;
node.data = obj;
return oldelement;
}
public Object get(int index) {
checkOutOfBoundsWhenSearch(index);
Node node = head.next;
for(int i = 0 ; i < index ; i ++)
node = node.next;
return node.data;
}
public void offer(Object obj) {
this.add(obj);
}
public Object poll() {
Object res = get(0);
remove(0);
return res;
}
public Object remove(int index) {
checkOutOfBoundsWhenAdd(index);
Node node = head;
for(int i = 0 ; i < index ; i ++)
node = node.next;
Object oldelment = node.next.data;
node.next = node.next.next;
size -- ;
return oldelment;
}
private void checkOutOfBoundsWhenAdd(int index)
{
if(index < 0 || index > size)
throw new ArrayIndexOutOfBoundsException(index);
}
private void checkOutOfBoundsWhenSearch(int index)
{
if(index < 0 || index >= size)
throw new NoSuchElementException();
}
public int size() {
return this.size;
}
public boolean isEmpty() {
return this.head.next == null;
}
public boolean contains(Object obj) {
Node node = head.next;
while(node != null)
{
if(node.data.equals(obj))
return true;
}
return false;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
Node p = head.next;
while(p != null) {
sb.append(p.data+", ");
p = p.next;
}
if(!this.isEmpty())
sb.delete(sb.lastIndexOf(","), sb.length());
sb.append(']');
return sb.toString();
}
}