前言
本章讲解顺序存储结构ArrayList的底层实现
方法
1.概念
我们知道,线性表的链式存储结构的实现在Java中是以LinkedList来实现的。那么我们用了这么久的LinkedList,如果不知道LinkedList的底层实现岂不是十分的滑稽,让我们来揭开它神秘的面纱。
2.实现思路
1)构建我们自己的List接口
我们可以尝试写出最基本的抽象方法。比如求集合中元素的个数方法等。
package cn.edu.ccut;
/**
* 模仿List接口
* @author wangjian
*
* @param <E>
*/
public interface List<E> {
public int size();//获得集合长度
public boolean add(E e);//新增对象
public E get(int index);//获得对象
public E remove(int index);//删除对象
public boolean isEmpty();//判断集合是否为空
public int indexOf(Object obj);//判断元素在集合中的位置
public boolean contains(Object obj);//判断元素是否在集合中
}
2)编写具体的实现类LinkedList
package cn.edu.ccut;
public class LinkedList<E> implements List<E> {
private int size;
private Node<E> first;//当前链表的第一个节点
private Node<E> last;//当前链表的最后一个节点
//定义节点静态内部类
private static class Node<E> {
E item; //数据对象
Node<E> next;//下一个节点
Node<E> prev;//前一个节点
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
@Override
public int size() {
return size;
}
@Override
public boolean add(E e) {
Node<E> l = last;//获取最后一个节点
Node<E> newNode = new Node<>(l, e, null);//要添加的新节点
last = newNode;
if(l == null){//没有数据
first = newNode;
}else {
l.next = newNode;//牵手最后一个节点
}
size++;
return true;
}
private void checkIndexOfLink(int index){
if( index < 0 || index > size-1){
String error = "index: "+index+",size: "+size;
throw new ArrayIndexOutOfBoundsException(error);
}
}
@Override
public E get(int index) {
checkIndexOfLink(index);
Node<E> currentNode = first;
for (int i = 0; i < index; i++) {
currentNode = currentNode.next;
}
return currentNode.item;
}
@Override
public E remove(int index) {
checkIndexOfLink(index);
//获取要删除的节点
Node<E> currentNode = first;
for (int i = 0; i < index; i++) {
currentNode = currentNode.next;
}
Node<E> currentPre = currentNode.prev;//当前节点的前驱
Node<E> currentNext = currentNode.next;//当前节点的后继
E currentItem = currentNode.item;//当前节点值
if(currentPre == null){
first = currentNext;//删除第一个元素无需拉手
}else {
currentPre.next = currentNext;//拉手
currentNode.prev = null;//放手
}
if(currentNext == null){
last = currentPre;//删除最后一个元素无需拉手
}else {
currentNext.prev = currentPre;//拉手
currentNode.next = null;//放手
}
currentNode.item = null;//数据置空
size--;
return currentItem;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public int indexOf(Object obj) {
int index = 0;
if (obj == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (obj.equals(x.item))
return index;
index++;
}
}
return -1;
}
@Override
public boolean contains(Object obj) {
return indexOf(obj) >= 0;
}
}
请大家仔细体会代码的实现细节。