(1) 手动实现LinkedList
LinkedList底层结构实现和ArrayList底层数据结构实现有着本质上的区别 ArrayList底层实现主要依赖数组,而LinkedList底层实现则是依赖链表。
/**
-
LinkedList的实现是双向链表,因此需要定义首节点和尾结点。
-
并且需要保存链表中元素的个数。此外,还需要提供无参构造方法,
-
在构造方法内初始化一个空链表。 */ public class MyLinkedList { private Node first; private Node last; private int size;
/**
-
在尾部添加节点
-
@param o
-
@return */ public boolean add(Object o){ if(size == 0){ Node newNode = new Node(null,o,null); first = newNode; last = newNode; }else{ //实例化新节点 Node newNode = new Node(last,o,null); last.next = newNode; last = newNode; } size++; return true; }
-
/*** 在指定索引处添加节点* @param index* @param o* @return*/ public boolean add(int index,Object o){if(index<0 || index>size){throw new IndexOutOfBoundsException("越界!");}if(index == 0){//获取指定索引处的节点Node newNode = getNode(index);//获取首节点的前置节点Node pre = first.pre;//首节点的前置节点指向新节点pre.next = newNode;//将新节点作为首节点first = newNode;size++;}if(index == size){//直接将对象添加到尾部add(o);}//获取索引的节点Node indexNode = getNode(index);//获取索引节点的前置节点Node preNode = indexNode.pre;//实例化新节点 per指向索引节点的前置节点,next指向索引节点的后置节点Node newNode = new Node(preNode,o,indexNode);//索引节点前置节点的next指向新节点preNode.next = newNode;//索引节点的pre指向新节点indexNode.pre = newNode;size++;return true; } /*** 删除对应索引处的节点* @param index* @return*/ public Object remove(int index){if(index<0 || index>=size){throw new IndexOutOfBoundsException("越界");}//初始化返回的值Object o = null;//删除首节点if(index ==0) {//获取首节点的节点值o = first.date;//获取首节点的后置节点Node node = first.next;//首节点的next为nullfirst.next = null;//将首节点的后置节点作为首节点first = node;}//删除尾节点else if(index == size-1){o = last.date;//获取尾节点的前置节点Node perNode = last.pre;//尾节点的前置节点的next置为nullperNode.next = null;//将索引节点的尾节点作为尾节点last = perNode;}else{//删除中间节点//获取索引处节点Node indexNode = getNode(index);o = indexNode.date;//获取索引节点的前置节点Node preNode = indexNode.pre;//获取索引节点的后置节点Node nextNode = indexNode.next;//将索引节点的前置节点指向索引节点的后置节点preNode.next = nextNode;//将索引节点的后置节点指向索引节点的前置节点nextNode.pre = preNode;//将索引节点的pre置为nullindexNode.pre = null;//将索引节点的next置为nullindexNode.next = null;}size--;return o; } /*** 修改索引处节点的元素值* @param index* @param o* @return*/ public Object set(int index,Object o){if(index<0||index>=size){throw new IndexOutOfBoundsException("越界!");}//获取对应索引处的节点Node indexNode = getNode(index);//获取要删除节点的值Object oldValue = indexNode.date;//将要修改的值赋值给目标节点indexNode.date = o;return oldValue; } /*** 获取双向链表的容量* @return*/ public int size(){return size; } /*** 获取对应索引处节点的元素值* @param index* @return*/ public Object get(int index){return getNode(index).date; } /*** 获取对应索引处的Node对象* @param index* @return*/ public Node getNode(int index){if(index<0 || index>=size){throw new IndexOutOfBoundsException("越界");}//获取首节点Node current = first;for (int i = 0; i < index&¤t!=null; i++) {//获取下一个节点current = current.next;}return current; } /*** 定义链表数据节点*/ private class Node{private Node pre;private Object date;private Node next; public Node(Node pre,Object o,Node next){this.pre = pre;this.date = o;this.next = next;} }
}
/**
-
测试类 */ public class Test { public static void main(String[] args) { MyLinkedList list = new MyLinkedList(); list.add("111"); list.add("222"); list.add("333"); list.add("444"); list.set(1,"777"); list.set(2,"888"); list.remove(0); list.remove(1); System.out.println("-------------"); for (int i = 0; i <list.size(); i++) { System.out.println(list.get(i)); } } }