ArrayList 和 LinkedList 的自定义实现


前言

      下面给出 ArrayList 和 LinkedList 的自定义实现,仅作为练习。

一、ArrayList

      自己仿照着写一个 SimpleArrayList 实现类,代码也比较简单,故不做说明了,其中 SimpleItr 内部类实现了 Iterator 接口。如下:


public class SimpleArrayList<T> implements Iterable<T> {

    private static final int DEFAULT_CAPACITY=10;
    private int capacity=DEFAULT_CAPACITY;
    private int Size;
    private T[] Items;
    public SimpleArrayList(){
        doClear();
    }
    public void clear(){
        doClear();
    }
    private void doClear(){
        Size=0;
        ensureCapacity(DEFAULT_CAPACITY);
    }

    public int size(){
        return Size;
    }
    public boolean isEmpty(){
        return size()==0;
    }
    public void trimToSize(){
        ensureCapacity(size());
    }
    public T get(int idx){
        if(idx<0||idx>=size())
            throw new ArrayIndexOutOfBoundsException();
        return Items[idx];
    }
    public void set(int idx,T newValue){
        if(idx<0||idx>=size())
            throw new ArrayIndexOutOfBoundsException();
        Items[idx]=newValue;
    }
    public void ensureCapacity(int newCapacity){
        if(newCapacity<Size)
            return;
        T[] old=Items;
        Items=(T[])new Object[newCapacity];
        for(int i=0;i<size();i++)
            Items[i]=old[i];
    }
    public void add(T x){
        add(size(),x);
    }
    public void add(int idx,T x){
        if(Items.length==size())//Items.length为数组容量
            ensureCapacity(size()*2+1);// +1 是为了避免数组为空时无法添加元素
        for(int i=size()-1;i>idx;i--)
            Items[i]=Items[i-1];
        Items[idx]=x;
        Size+=1;
    }
    public void remove(int idx){
        if(idx<0||idx>=size())
            throw new ArrayIndexOutOfBoundsException();
        for(int i=idx;i<size()-1;i++)
            Items[i]=Items[i+1];
        Size-=1;
    }
    public Iterator<T> iterator(){
        return new SimpleItr();
    }
    private class SimpleItr implements Iterator<T>{//内部类
        private int current=0;//当前位置(从0开始)
        public boolean hasNext(){
            return current<size();
        }
        public T next(){
            if(!hasNext())
                throw new NoSuchElementException();
            return Items[current++];
        }
        public void remove(){
            SimpleArrayList.this.remove(--current);
        }
    }

}

二、LinkedList

      LinkedList 内部采用双链表来实现,如果操作发生在已知的情况下(端点或由迭代器指定的位置上),从而保证每个操作花费常数时间。

      1,SimpleLinkedList 类,包含双链表和一些方法。
      2,Node 静态内部类。实现链表中的节点。
      3,SimpleItr 内部类。实现了 Iterator 接口。

public class SimpleLinkedList<T> implements Iterable<T> {
    private static class Node<T>{//Node 静态内部类(改为非静态内部类也可以)
        public T value;
        public Node<T> pre;
        public Node<T> next;
        public Node(T value,Node<T> pre,Node<T> next){
            this.value=value;this.pre=pre;this.next=next;
        }
    }
    private int size;
    private Node<T> header,tail;//头尾节点
    public SimpleLinkedList(){
        doClear();
    }
    public void clear(){
        doClear();
    }
    private void doClear(){
        header=new Node<T>(null,null,null);
        tail=new Node<T>(null,header,null);
        header.next=tail;
        size=0;
    }
    public int size(){
        return size;
    }
    public boolean isEmpty(){
        return size()==0;
    }

//get 和 set 方法。
    private Node<T> getNode(int idx){ //工具方法,稍微加快了搜索效率。
        Node<T> tmp;
        if(idx<0||idx>=size()){
            throw new IndexOutOfBoundsException();
        }
        if(idx<size()/2){
            tmp=header.next;
            for(int i=0;i<idx;i++)
                tmp=tmp.next;
        }
        else{
            tmp=tail.pre;
            for(int i=size()-1;i>idx;i--)
                tmp=tmp.pre;
        }
        return tmp;
    }
    public T get(int idx){
        return getNode(idx).value;
    }
    public void set(int idx,T ele){
        Node<T> tmp=getNode(idx);
        tmp.value=ele;
    }

//add 和 remove 方法。
    public void add(T x){//尾插法
        Node<T> newPre=tail.pre;
        Node<T> tmp=new Node<>(x,newPre,tail);
        tail.pre=tmp;
        newPre.next=tmp;
        size++;
    }
    public void add(int idx,T x){
        Node<T> oldNode=getNode(idx);
        Node<T> newPre=oldNode.pre;
        Node<T> tmp=new Node<>(x,newPre,oldNode);
        newPre.next=tmp;
        oldNode.pre=tmp;
        size++;
    }
    public void remove(int idx){
        Node<T> node=getNode(idx);
        Node<T> pre=node.pre;
        Node<T> next=node.next;
        pre.next=next;
        next.pre=pre;
        size--;
    }

//iterator 方法。
    public Iterator<T> iterator(){
        return new SimpleItr();
    }
    private class SimpleItr implements Iterator<T>{
        private Node<T> current=header.next;
        private boolean okToRemove=false;
        public boolean hasNext(){
            return current!=tail;
        }
        public T next(){
            if(!hasNext())
                throw  new NoSuchElementException();
            T nextItem=current.value;
            current=current.next;
            okToRemove=true;
            return nextItem;
        }
        public void remove(){
            if(!okToRemove)
                throw new IllegalStateException();
            Node<T> currentTmp=current.pre;
            currentTmp.pre.next=current;
            current.pre=currentTmp.pre;
            okToRemove=false;
        }
    }
}

总结

      完。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值