一、LinkedList原理介绍
LinkedList是java中重要的List集合,其内部是一个双向链的数据结构。插入和删除的效率比ArrayList高,之前手动实现的ArrayList,因为插入和删除没有数组的复制工作,如果想在下标为index位置插入元素则通过从头部或者尾部开始查找,找到index原始位置的元素,则修改原始位置index元素的Node中的上一个元素,以及元素index元素前一个元素Node的下一个元素。只需要修改两个元素就可以实现元素的插入。(List元素越大则LinkedList插入/删除的效率相比ArrayList)会更好。
二、LinkedList实现代码
package list;
import java.util.NoSuchElementException;
/**
* 实现一个双向链表
* @author ocean
*
*/
public class MyLinkedList<E> {
private int size;
private Node<E> firstNode;
private Node<E> lastNode;
private class Node<E>{
private E item;
private Node<E> preNode;
private Node<E> nextNode;
public Node(E item, Node<E> preNode, Node<E> nextNode) {
this.item = item;
this.preNode = preNode;
this.nextNode = nextNode;
}
}
/**
* 根据下标获取元素
* @param index
* @return
*/
public E get(int index) {
//数组越界
if(!checkElementIndex(index)) {
throw new IndexOutOfBoundsException();
}
return getNode(index).item;
}
/**
* 尾部追加一个元素
* @param e
* @return
*/
public boolean add(E e) {
linkedLast(e);
return true;
}
/**
* 头部插入一个元素
* @param e
* @return
*/
public boolean addFirst(E e) {
linedFirst(e);
return true;
}
/**
* 向下标index插入元素
* @param index
* @param e
* @return
*/
public boolean add(int index,E e) {
if(index==size) {
linkedLast(e);
}else {
addBefore(index, e);
}
return true;
}
/**
* 根据下标删除元素
* @param index
* @return
*/
public E remove(int index) {
return unlink(getNode(index));
}
/**
* 删除第一个元素
* @return
*/
public E removeFirst() {
return unlinkFirst();
}
public E removeLast() {
return unlinkLast();
}
E unlinkLast() {
Node<E> l = lastNode;
if(l == null) {
throw new NoSuchElementException();
}
E element = l.item;
Node<E> pre = l.preNode;
l.item = null;//help gc
l.preNode = null;//help gc
if(pre == null) {
firstNode = null;
}else {
lastNode = pre;
}
size --;
return element;
}
E unlinkFirst() {
Node<E> f = firstNode;
if(f == null) {
throw new NoSuchElementException();
}
E element = f.item;
Node<E> next = f.nextNode;
f.item = null;
f.nextNode = null;
if(next == null) {
lastNode = null;
}
firstNode = next;
size --;
return element;
}
/**
* 向链表尾部插入元素
* @param e
*/
void linkedLast(E e) {
Node<E> x = lastNode;
Node<E> newNode = new Node<>(e, x, null);
lastNode = newNode;
if(x ==null) {
firstNode = newNode;
}else {
x.nextNode = newNode;
}
size ++;
}
/**
* 向链表头部插入元素
* @param e
*/
void linedFirst(E e) {
Node<E> x = firstNode;
Node<E> newNode = new Node<>(e, null, x);
if(x ==null) {
firstNode = newNode;
}else {
firstNode.preNode = newNode;
}
size ++;
}
/**
* 向下标index插入元素
* @param index
* @param e
*/
void addBefore(int index, E e) {
if(!checkElementIndex(index)) {
throw new IndexOutOfBoundsException();
}
Node<E> oldNode = getNode(index);
Node<E> preNode = oldNode.preNode;
Node<E> newNode = new Node<>(e, preNode, oldNode);
if(preNode ==null) {
firstNode = newNode;
}else {
preNode.nextNode = newNode;
}
size ++;
}
private Node<E> getNode(int index) {
if(index > (size>>1)) {//从尾部开始查询(二分查找思想)
Node<E> result = lastNode;
for(int i=size-1;i>index;i--) {
result = result.preNode;
}
return result;
}else {//从首部开始查询
Node<E> result = firstNode;
for(int i=0;i<index;i++) {
result = result.nextNode;
}
return result;
}
}
private E unlink(Node<E> e) {
E element = e.item;
Node<E> preNode = e.preNode;
Node<E> nextNode = e.nextNode;
if(preNode ==null) {
firstNode = nextNode;
}else {
preNode.nextNode = nextNode;
e.preNode = null;
}
if(nextNode==null) {
lastNode = preNode;
}else {
nextNode.preNode = preNode;
e.nextNode = null;
}
e.item = null;
size --;
return element;
}
private boolean checkElementIndex(int index) {
if(index <0 || index >=size) {
return false;
}
return true;
}
public static void main(String[] args) {
MyLinkedList<String> myList = new MyLinkedList<String>();
myList.add("String1");
myList.add("String2");
myList.add("String3");
myList.add("String4");
myList.add("String5");
myList.add("String6");
myList.add("String7");
myList.add(3, "2222222222222");
for(int i=0;i<myList.size;i++) {
System.out.println(myList.get(i));
}
System.out.println("===========开始删除下标为3的元素===========");
myList.remove(3);
for(int i=0;i<myList.size;i++) {
System.out.println(myList.get(i));
}
System.out.println("============删除头部元素==========");
myList.removeFirst();
for(int i=0;i<myList.size;i++) {
System.out.println(myList.get(i));
}
System.out.println("==========删除尾部元素============");
myList.removeLast();
for(int i=0;i<myList.size;i++) {
System.out.println(myList.get(i));
}
}
}
三、运行结果
String1
String2
String3
2222222222222
String4
String5
String6
String7
===========开始删除下标为3的元素===========
String1
String2
String3
String4
String5
String6
String7
============删除头部元素==========
String2
String3
String4
String5
String6
String7
==========删除尾部元素============
String2
String3
String4
String5
String6