LinkedList是一个实现了List接口和Deque接口的双端链表。 LinkedList底层的链表结构使它支持高效的插入和删除操作,另外它实现了Deque接口,使得LinkedList类也具有队列的特性; LinkedList不是线程安全的,如果想使LinkedList变成线程安全的,可以调用静态类Collections类中的synchronizedList方法:
LinedList维护了一个Node节点对象,实现如下
public class Node {
Node previous;
Object element;
Node next;
public Node(Node previous, Object element, Node next) {
super();
this.previous = previous;
this.element = element;
this.next = next;
}
public Node(Object element) {
super();
this.element = element;
}
}
简单实现
/**
* 自定义LinkedList
* Copyright © 2019 WRF. All rights reserved.
* 功能描述:
* @Package: org.wrf.collections
* @author: knight
* @date: 2019年3月19日 上午11:10:41
*/
public class MyLinkedList {
Node first;
Node last;
public void add(Object obj) {
Node node=new Node(obj);
if(first==null) {//当前节点是第一个节点
first=node;
last=node;
}else {//当前节点不是第一个节点
//初始化节点
node.previous=last;
node.next=null;
//last指针移动
last.next=node;
last=node;
}
}
//重写toString方法
@Override
public String toString() {
StringBuilder sb=new StringBuilder();
Node temp=first;
sb.append("[");
while(temp!=null) {
sb.append(temp.element+",");
temp=temp.next;
}
sb.setCharAt(sb.length()-1,']');
return sb.toString();
}
public static void main(String[] args) {
MyLinkedList myList=new MyLinkedList();
myList.add(1);
myList.add(2);
myList.add(3);
System.out.println(myList);
}
}
新增get()方法
/**
* 根据索引获取节点内容
* @param index
* @return 节点内容
*/
public Object get(int index) {
//索引越界检查
if(index<0||index>size-1) {
throw new RuntimeException("索引不合法:"+index);
}
//数据查找优化
Node temp=null;
//对于链表前半部分可以从first开始向后查找
if(index<=(size>>1)) {
temp=first;
for(int i=0;i<index;i++) {
temp=temp.next;
}
}else {
//对于链表后半部分可以从last开始向前查找
temp=last;
for(int i=size-1;i>index;i--) {
temp=temp.previous;
}
}
return temp.element;
}
新增remove方法,优化get方法
/**
* 移除元素
* @param index
*/
public void remove(int index) {
//获取该节点
Node temp=getNode(index);
if(temp!=null) {
Node up=temp.previous;
Node down=temp.next;
//修改前后节点指向
if(up!=null) {
up.next=down;
}
if(down!=null) {
down.previous=up;
}
//特殊情况(0||size-1)
if(index==0) {
first=down;
}
if(index==size-1) {
last=up;
}
size--;
}
}
/**
* 根据索引获取节点内容
* @param index
* @return 节点内容
*/
public Object get(int index) {
Node temp=getNode(index);
return temp!=null?temp.element:null;
}
/**
* 获取指定节点
* @param index
* @return 该节点
*/
public Node getNode(int index) {
//索引越界检查
if(index<0||index>size-1) {
throw new RuntimeException("索引不合法:"+index);
}
//数据查找优化
Node temp=null;
//对于链表前半部分可以从first开始向后查找
if(index<=(size>>1)) {
temp=first;
for(int i=0;i<index;i++) {
temp=temp.next;
}
}else {
//对于链表后半部分可以从last开始向前查找
temp=last;
for(int i=size-1;i>index;i--) {
temp=temp.previous;
}
}
return temp;
}
新增指定节点插入元素方法
public void add(int index,Object obj) {
//创建一个新节点
Node newNode=new Node(obj);
if(index==size) {
newNode.previous=last;
newNode.next=null;
//last指针移动
last.next=newNode;
last=newNode;
size++;
return;
}
//获取插入位置的节点
Node temp=getNode(index);
if(temp!=null) {
if(index==0) {
first=newNode;
newNode.next=temp;
temp.previous=newNode;
}else{
Node up=temp.previous;
//修改前指针指向
up.next=newNode;
newNode.previous=up;
//修改当前指针指向
newNode.next=temp;
temp.previous=newNode;
}
size++;
}
}
最后,泛型替换
package org.wrf.collections.List;
/**
* 自定义LinkedList
* Copyright © 2019 WRF. All rights reserved.
* 功能描述:
* 1.添加get()方法
* 2.添加remove()方法
* 3.添加add()方法
* 4.增加泛型
* @Package: org.wrf.collections
* @author: knight
* @date: 2019年3月19日 上午11:10:41
*/
public class MyLinkedList05<E> {
Node first;
Node last;
int size;
public void add(int index,E obj) {
//创建一个新节点
Node newNode=new Node(obj);
if(index==size) {
newNode.previous=last;
newNode.next=null;
//last指针移动
last.next=newNode;
last=newNode;
size++;
return;
}
//获取插入位置的节点
Node temp=getNode(index);
if(temp!=null) {
if(index==0) {
first=newNode;
newNode.next=temp;
temp.previous=newNode;
}else{
Node up=temp.previous;
//修改前指针指向
up.next=newNode;
newNode.previous=up;
//修改当前指针指向
newNode.next=temp;
temp.previous=newNode;
}
size++;
}
}
/**
* 移除元素
* @param index
*/
public void remove(int index) {
//获取该节点
Node temp=getNode(index);
if(temp!=null) {
Node up=temp.previous;
Node down=temp.next;
//修改前后节点指向
if(up!=null) {
up.next=down;
}
if(down!=null) {
down.previous=up;
}
//特殊情况(0||size-1)
if(index==0) {
first=down;
}
if(index==size-1) {
last=up;
}
size--;
}
}
/**
* 根据索引获取节点内容
* @param index
* @return 节点内容
*/
@SuppressWarnings("unchecked")
public E get(int index) {
Node temp=getNode(index);
return temp!=null?(E)temp.element:null;
}
/**
* 索引检查
* @param index
*/
public void checkRange(int index) {
//索引越界检查
if(index<0||index>size-1) {
throw new RuntimeException("索引不合法:"+index);
}
}
/**
* 获取指定节点
* @param index
* @return 该节点
*/
public Node getNode(int index) {
checkRange(index);
//数据查找优化
Node temp=null;
//对于链表前半部分可以从first开始向后查找
if(index<=(size>>1)) {
temp=first;
for(int i=0;i<index;i++) {
temp=temp.next;
}
}else {
//对于链表后半部分可以从last开始向前查找
temp=last;
for(int i=size-1;i>index;i--) {
temp=temp.previous;
}
}
return temp;
}
/**
* 新增节点
* @param obj
*/
public void add(E obj) {
Node node=new Node(obj);
if(first==null) {//当前节点是第一个节点
first=node;
last=node;
}else {//当前节点不是第一个节点
//初始化节点
node.previous=last;
node.next=null;
//last指针移动
last.next=node;
last=node;
}
size++;
}
//重写toString方法
@Override
public String toString() {
StringBuilder sb=new StringBuilder();
Node temp=first;
sb.append("[");
while(temp!=null) {
sb.append(temp.element+",");
temp=temp.next;
}
sb.setCharAt(sb.length()-1,']');
return sb.toString();
}
public static void main(String[] args) {
MyLinkedList05<String> myList=new MyLinkedList05<String>();
myList.add("1");
myList.add("2");
myList.add("3");
myList.add("4");
myList.add("hello");
myList.add("world");
System.out.println(myList.size);
System.out.println(myList);
myList.add(0,"hhhhh");
System.out.println(myList.size);
}
}