使用链式结构进行封装

1.在IndexBox接口中定义规则 使用泛型讲不确定的数据类型定义成<E>

package com.buka;

public interface IndexBox<E> extends Box<E> {

    /**
     * 得到指定位置的数据
     * @param i 指定的位置
     * @return 得到的数据
     */
    E get(int i);

    /**
     * 将数据放到指定的位置
     * @param e 存放的数据
     * @param i 要存放的位置
     * @return 为true表示存储成功,为false表示存储失败
     */
    boolean add(E e, int i);

    /**
     * 将一组数据放到指定的位置
     * @param es 要存放的一组数据
     * @param i 要存放的位置
     * @return 为true表示存储成功,为false表示存储失败
     */
    boolean add(E[] es, int i);

    /**
     * 将另一个容器里的数据放到当前容器的指定的位置
     * @param box 要存放的另一个容器
     * @param i 要存放的位置
     * @return 为true表示存储成功,为false表示存储失败
     */
    boolean add(Box<? extends E> box, int i);

    /**
     * 删除指定位置的数据
     * @param i 要删除的位置
     * @return 删除的数据
     */
    E remove(int i);
}

对于IndexBox的规则定义需要新创建Manager接口用于辅助实现

package com.buka;

public interface Manager<E> {

    /**
     * 判断是否还有下一个数据
     * @return true表示有下一个数据,false表示没有
     */
    boolean hasNext();

    /**
     * 得到当前指针只向的数据,并向下移动指针
     * @return 得到的数据
     */
    E getNext();

    /**
     * 判断是否还有上一个数据
     * @return true表示有上一个数据,false表示没有
     */
    boolean hasPrev();

    /**
     * 得到当前指针只向的数据,并向上移动指针
     * @return 得到的数据
     */
    E getPrev();

    /**
     * 得到box中存储的第一个数据
     * @return 得到的数据
     */
    E getFirst();

    /**
     * 得到box中存储的最后一个数据
     * @return 得到的数据
     */
    E getLast();

    /**
     * 重写开始记录指针在box中的位置
     */
    void reStart();
}

2.将定义好的规则打包 导入新的项目 在新的项目中对规则进行重写

创建LinkedBox 继承IndexBox

生成重写方法 并进行重写

package com.buka;


public class LinkedBox<E> implements IndexBox<E> {
    class Node<T> {
        //节点中的数据
        T element;
        //节点中上一个节点的地址
        Node<T> prev;
        //节点中下一个节点的地址
        Node<T> next;

        public Node() {
        }

        public Node(T element, Node<T> next, Node<T> prev) {
            this.element = element;
            this.next = next;
            this.prev = prev;
        }
    }

    //记录头节点,就可以得到整个链表
    private Node<E> first;
    //记录尾节点,也可以得到整个链表
    private Node<E> last;
    //记录存储元素的数量(节点的数量)
    private int size = 0;


    private void checkIndex(int i){
        if(i <0|| i>=size){
            throw new BoxIndexOutOfBoundsException("Size:"+size+",Index:"+i);
        }
    }
    @Override
    public E get(int i) {
        checkIndex(i);
        return find(i).element;
    }

    private Node<E> find(int i) {
        //i = 0;
        int count = 0;
        Node<E> curr = first;
        while (count < i) {
            curr = curr.next;
            count++;
        }
        return curr;
    }

    @Override
    public boolean add(E e, int i) {
        if (i < 0 || i > size) {
            throw new BoxIndexOutOfBoundsException("Size" + size + ",Index" + i);
        }
        Node<E> n = find(i);
        if (n == null) {
            add(e);
            return true;
        }
        Node<E> newNode = new Node<E>();
        newNode.element = e;
        if (n.prev == null) {
            //n就是first
            newNode.next = n;
            n.prev = newNode;
            first = newNode;
            size++;
            return true;
        }

        n.prev.next = newNode;
        n.prev = newNode;
        newNode.prev = n.prev;
        newNode.next = n;
        size++;
        return true;
    }

    @Override
    public boolean add(E[] es, int i) {
        for (E e : es) {
            add(e, i++);
        }
        return true;
    }

    @Override
    public boolean add(Box<? extends E> box, int i) {
        Manager<? extends E> manager = box.getManager();
        while (manager.hasNext()) {
            E next =manager.getNext();
            add(next,i++);
        }
        return true;
    }

    @Override
    public E remove(int i) {
        checkIndex(i);

        Node<E> n = find(i);

        if(n.next == null){
            //n是最后一个
            last = n.prev ;
            n.prev.next = null ;
            n.prev = null ;
        }else if(n.prev  == null){
            //n是第一个节点
            first = n.next ;
            n.next.prev = null ;
            n.next = null ;
        }else{
            //n是中间的节点
            Node<E> prev = n.prev ;
            Node<E> next = n.next ;
            n.prev = null ;
            n.next = null ;
            prev.next = next ;
            next.prev = prev ;
        }
        size -- ;
        return n.element;

    }

    @Override
    public boolean add(E e) {
        //添加元素,对于链表结构而言,每一个元素在链表中都是以节点的形式存储
        Node<E> newNode = new Node<E>();
        newNode.element = e;
        if (first == null) {
            //链表中一个节点都没有
            //当前这个节点,又是头节点,又尾节点
            first = newNode;
            last = newNode;
        } else {
            //链表中本身就有一些节点
            //此时新节点应该放在之前那个last节点的后面
            //放完之后,当前这个新节点就变成了last节点

            last.next = newNode; //null.xxx  last = null
            newNode.prev = last;
            last = newNode;
        }
        size++;
        return true;
    }

    @Override
    public boolean add(E[] es) {
        for (int i = 0; i < es.length; i++) {
            add(es[i]);
        }
        return true;
    }

    @Override
    public boolean add(Box<? extends E> box) {
        Manager<? extends E> manager = box.getManager();
        while (manager.hasNext()) {
            E e = manager.getNext();
            add(e);
        }
        return true;
    }

    @Override
    public Manager<E> getManager() {
        return new LinkedManager<E>();
    }

    private class LinkedManager<E> implements Manager<E>{

        private Node<E> curr = (Node<E>) first;
        private Node<E> curr2 = (Node<E>) last;

        @Override
        public boolean hasNext() {
            return curr != null ;
        }

        @Override
        public E getNext() {
            try {
                return curr.element;
            }finally {
                curr = curr.next ;
            }
        }

        @Override
        public boolean hasPrev() {
            return curr2 != null;
        }

        @Override
        public E getPrev() {
            try{
                return curr2.element;

            }finally {
                curr2 =curr2.prev ;
            }
        }

        @Override
        public E getFirst() {
            return (E) first.element;
        }

        @Override
        public E getLast() {
            return (E) last.element;
        }

        @Override
        public void reStart() {
            curr = (Node<E>) first;
        }
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public void show() {
        //打印存储的所有元素
        //所有的元素都在节点中存储
        //怎么能得到所有的节点呢?
        //可以从头结点,一个一个的往后找。也可以从尾节点一个一个的往前找
        Node<E> curr = first;
        while (curr != null) {
            E e = curr.element;
            System.out.println(e);
            curr = curr.next;
        }

    }
}

3.在重写过程中我新定义了一个异常 用于处理IndexBox出现不合理数据或不合法范围。

package com.buka;

public class BoxIndexOutOfBoundsException extends RuntimeException{
    BoxIndexOutOfBoundsException(){}
    BoxIndexOutOfBoundsException(String msg){
        super(msg);
    }
}

4.最后对于我进行的链式封装进行测试

    public static void main(String[] args) {
        LinkedBox<String> box = new LinkedBox<>();
        box.add("car1");
        box.add("car2");
        box.add("car3");
        box.show();
        System.out.println("---------------------------");
        Manager<String> manager = box.getManager();
        while (manager.hasNext()) {
            String next = manager.getNext();
            System.out.println(next.toUpperCase());
        }
        System.out.println("---------------------------");
        LinkedBox<String> box2 = new LinkedBox<String>();
        box2.add("car4");
        box2.add("car5");
        box2.add("car5");
        box.add(box2);
        box.show();
        System.out.println("---------------------------");
        IndexBox box1 = box;
        box1.add("car6",1);
        box1.show();
        System.out.println("---------------------------");
        box1.remove(2);
        box1.show();
    }

5.对此我们完成了链式封装

在进行完善的时候我遇到了 算法逻辑 等问题并积极学习改进

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值