1、简介

使用数组来存储数据的一个缺点是,数组是静态的结构,因此 不能被容易的扩展或减少数据集。维护新数组也贵 插入和删除。 在这一章里,我们考虑另一个名为链表的数据结构 地址的一些局限性数组。

一个链表是一个线性数据结构,其中每个元素是一个单独的 对象。


每个元素(我们叫它节点的两个项目——组成的列表 数据和到下一个节点的引用。 最后一个节点的引用null。 入口点到链表称为头的列表。 应该注意,头 不是一个单独的节点,而是第一个节点的引用。 如果列表为空,那么是一个主管 空引用。

一个链表是一个动态的数据结构。 列表中的节点的数目是不固定的,可以生长 对需求和收缩。 任何应用程序的处理需要数量未知的对象 使用链表。

对数组链表的一个缺点是它不允许 直接访问单个元素。 如果你想访问一个特定的项目 你必须从头部开始,遵循项目的引用,直到你到达。

另一个缺点是,链表使用更多的内存与——我们额外的数组 4个字节(32位CPU)存储到下一个节点的引用。

2、链表分类

链表分类

单链表   

可以通过后驱找到后续节点

双链表

有前驱和后驱,可以找到前驱结点和后继结点

循环链表

最后一个节点的后驱是第一个节点

3、构造方法


LinkedList() 

          构造一个空列表。

LinkedList(Collection<? extendsE> c)           构造一个包含指定 collection 中的元素的列表,这些元素按其 collection 的迭代器返回的顺序排列。

4、方法摘要



 boolean

add(E           将指定元素添加到此列表的结尾。

  void

add(int index,E           在此列表中指定的位置插入指定的元素。

 boolean

addAll(Collection<? extendsE> c)           添加指定 collection 中的所有元素到此列表的结尾

 boolean

addAll(int index,Collection<? extendsE> c)           将指定 collection 中的所有元素从指定位置开始插入此列表。

   void

addFirst(E           将指定元素插入此列表的开头。

   void

addLast(E           将指定元素添加到此列表的结尾。


clear()           从此列表中移除所有元素。

Object

clone()           返回此 LinkedList

 boolean

contains(Object           如果此列表包含指定元素,则返回 true。

 Iterator<E>

descendingIterator()           返回以逆向顺序在此双端队列的元素上进行迭代的迭代器。

    E

element()           获取但不移除此列表的头(第一个元素)。

    E

get(int index)           返回此列表中指定位置处的元素。

    E

getFirst()           返回此列表的第一个元素。

    E

getLast()           返回此列表的最后一个元素。

 int

indexOf(Object           返回此列表中首次出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1。

 int

lastIndexOf(Object           返回此列表中最后出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1

 Iterator<E>

listIterator(int index)           返回此列表中的元素的列表迭代器(按适当顺序),从列表中指定位置开始。

 boolean

offer(E           将指定元素添加到此列表的末尾(最后一个元素)。

 boolean

offerFirst(E           在此列表的开头插入指定的元素

 boolean

offerLast(E           在此列表末尾插入指定的元素。

    E

peek()           获取但不移除此列表的头(第一个元素)。

    E

peekFirst()           获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。

    E

peekLast()           获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null

    E

poll()           获取并移除此列表的头(第一个元素)

    E

pollFirst()         null。

    E

pollLast()          null。

    E

pop()           从此列表所表示的堆栈处弹出一个元素。

 void

push(E           将元素推入此列表所表示的堆栈。

    E

remove()           获取并移除此列表的头(第一个元素)。

    E

remove(int index)           移除此列表中指定位置处的元素。

   boolean

remove(Object           从此列表中移除首次出现的指定元素(如果存在)。

    E

removeFirst()           移除并返回此列表的第一个元素。

 boolean

removeFirstOccurrence(Object           从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表时)。

   E

removeLast()           移除并返回此列表的最后一个元素。

boolean

removeLastOccurrence(Object           从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表时)。

   E

set(int index,E           将此列表中指定位置的元素替换为指定的元素。

  int

size()           返回此列表的元素数

 Object[]

toArray()           返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组。



toArray(T[] a)           返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组;返回数组的运行时类型为指定数组的类型。

12

12

<T> T[]



5、部分代码

1、添加、获取、删除、遍历


public class TestLinkedList {
	public static void main(String[] args) {
		LinkedList<String> books = new LinkedList();

		// 把元素添加到列表的结尾
		books.add("A");
		books.add("B");
		books.add("C");

		// 把元素添加到列表的第一个位置
		books.addFirst("1");

		// 把元素添加到列表的最后一个位置
		books.addLast("8");

		// 把元素添加到列表的最后一个位置
		books.offer("X");

		// 把元素添加到列表的第一个位置
		books.offerFirst("0");

		// 把元素添加到列表的最后一个位置
		books.offerLast("9");

		// 遍历方法一
		Iterator<String> iter = books.iterator();
		while (iter.hasNext()) {
			String element = iter.next();
			System.out.print(element);
		}
		// 输出 :01ABC8X9

		// 遍历方法二
		for (String str : books) {
			System.out.print(str);
		}
		// 输出 :01ABC8X9

		// 获取链表的第一个元素,并且不移除
		// 方法一
		System.out.println(books.getFirst());
		// 方法二
		System.out.println(books.element());
		// 方法三
		System.out.println(books.peek());
		// 方法四
		System.out.println(books.peekFirst());

		// 获取第一个元素并且移除
		// 方法一
		System.out.println(books.poll());
		// 方法二
		System.out.println(books.pollFirst());
		// 方法三
		System.out.println(books.remove());
		// 方法四
		System.out.println(books.removeFirst());

		// 遍历方法三,到序遍历
		iter = books.descendingIterator();
		while (iter.hasNext()) {
			String element = iter.next();
			System.out.print(element);
		}

		// 获取子链表
		System.out.println(books.subList(0, 2));
		// 删除指定位置的元素
		books.subList(0, 2).clear();
		for (String str : books) {
			System.out.print(str);
		}
	}
}




2、实现栈的效果

public class TestLinkedListandSXtack {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyStacks ms = new MyStacks();
		//入栈
		ms.Push("A");
		ms.Push("B");
		ms.Push("C");
		//LinkedList 转 ArrayList
		ms.Show();
		
		//获取栈顶元素
		System.out.println(ms.Top());
	
		
		//连续出栈
		System.out.println(ms.Pop());
		System.out.println(ms.Pop());
		System.out.println(ms.Pop());
	}

}
class MyStacks
{
	private LinkedList<Object> list = new LinkedList<Object>();
	
	public void Show(){
		//LinkedList 转 ArrayList
		ArrayList<Object> ay = new ArrayList<Object>(list);
		for(Object str:ay){
			System.out.print(str);
		}
		System.out.println();
	}
	
	//获取栈顶元素
	public Object Top(){
		return list.getFirst();//list.element();
	}
	//入栈
	public void Push(Object o){
		list.addFirst(o);
	}
	//出栈
	public Object Pop(){
		return list.remove();
	}
}



3、实现队列的效果

<p><span style="font-weight: normal;">package com.jlz;
import java.util.*;
public class TestLinkedListAndQueue {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyQueue queue = new MyQueue();
		queue.Put("A");
		queue.Put("B");
		queue.Put("C");
		
		while(!queue.isEmpty()){
			System.out.print(queue.Get());
		}
	}
}
class MyQueue
{
	LinkedList<Object> list = new LinkedList<Object>();
	//入队列,添加到队尾
	public void Put(Object o){
		list.addLast(o);
	}
	//出队列
	public Object Get(){
		return list.removeFirst();
	}
	//判断是否为空
	boolean isEmpty(){
		return list.isEmpty();
	}
}
</span></p>


4、转换为数组(长度为0,长度为链表长度)、转换为ArrayList

package com.jlz;
import java.util.*;
public class LinkedListChangeIndex {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		LinkedList<String> list =  new LinkedList<String>();
		list.add("A");
		list.add("B");
		list.add("C");
		//转为数组,数组长度为0
		String str[] = list.toArray(new String[0]);
		for(String s:str){
			System.out.print(s);
		}
		//转为数组,数组长度为链表长度
		String string[] = list.toArray(new String[list.size()]);
		for(String s:string){
			System.out.print(s);
		}
		//转为ArrayList
		ArrayList<String> alist = new ArrayList<String>(list);
		for(Object o:alist){
			System.out.print(o);
		}
	}

}

5、同步


package com.jlz;
import java.util.*;
public class LinkedListStackSynchronized {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		LinkedList<Object> stack = new LinkedList<Object>();
		stack.addFirst("A");
		stack.addFirst("B");
		stack.addFirst("C");
		//同步
		stack = (LinkedList<Object>)Collections.synchronizedList(stack);
	}

}