自定义数组列表和队列

  最近一直在研究数据结构与算法,涉及到自定义数组和队列,感觉对JDK源代码的底层功能实现学习有一定的帮助,故作此总结,以供参考。

  ps:JDK的源代码更加复杂,我的自定义数组列表和队列只是一些简单的逻辑实现。

1.自定义数组列表(MyArrayList.java)

package com.BlueStarWei.arrayList;

/**
 * 
 * show all fields and method,please click "ctrl + o"
 * 
 * 
 * 开发过程遇到的问题:
 * 1. 传入下标(index)未考虑越界情况
 *             一定要校验指针是否越界
 * 2. 当容量耗尽后,如何拓展新的空间
 *         添加一个变量(hasInitCapacity),用于判断数组的创建方式。
 *         如果是通过无参构造方式创建(hasInitCapacity = false),每次扩展容量的时候在原有数组长度的基础上增加拓展长度。
 * 
 * @author HuWei
 *
 * @param <E>
 */
public class MyArrayList<E> {
    /**
     * The default capacity while use constructor form superClass
     */
    private final int DEFUALT_CAPACITY = 10;
    
    /**
     * The expending capacity while arr that is generated via constructor form superClass is full 
     */
    private final int ADD_CAPACITY = DEFUALT_CAPACITY / 2;
    
    /**
     * The array to store elements
     */
    private E[] arr;
    
    /**
     * The length of element to be stored into arr
     */
    private int size;
    
    /**
     * check whether is the queue generated by constructor with initCapacity
     */
    private boolean hasInitCapacity;
    
    public MyArrayList() {
        arr = (E[]) new Object[DEFUALT_CAPACITY];
        hasInitCapacity = false;
    }
    
    public MyArrayList(int initCapacity){
        arr = (E[]) new Object[initCapacity];
        hasInitCapacity = true;
    }
    
    /**
     * 
     * @return
     *         the length of array
     */
    public int size() {
        return size;
    }

    /**
     * let element insert to arr
     * if MyArrayList is generated via constructor form superClass and the capacity is full,then expand capacity
     * @param element   
     *         the element to insert
     * @return index    
     *         the index of the element to insert
     */
    public int add(E element){
        //expend capacity
        if(!hasInitCapacity && size == arr.length){
            E[] arr2 = arr;
            arr = (E[]) new Object[arr.length + ADD_CAPACITY];
            for (int i = 0; i < arr2.length; i++) {
                arr[i] = arr2[i];
            }
        }
        arr[size] = element;
        return size++;
    }
    
    /**
     * 
     * @param index
     *         the index of the element to replace
     * @param element    
     *         the element to replace
     * @return
     *         the element to be replaced
     */
    public E update(int index, E element){
        checkArange(index);
        E old = arr[index];
        arr[index] = element;
        return old;
    }
    
    /**
     * 
     * @param index
     *         the index of the element to be removed
     * @return
     *         the element to be removed
     */
    public E remove(int index){
        checkArange(index);
        
        E element = arr[index];
        if(index == size - 1){
            arr[index] = null;
        }
        for (int i = index; i < size; i++) {
            arr[i] = arr[i+1];
        }
        size--;
        return element;
    }
    
    /**
     * 
     * @param index
     *         the index of the element to get
     * @return
     *         the element to get
     */
    public E get(int index){
        return arr[index];
    }
    
    /**
     * check whether index is out of bounds
     * @param index
     */
    private void checkArange(int index){
        if(index < 0 || index >= size){
            throw new ArrayIndexOutOfBoundsException();
        }
    }
    
    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        result.append("[");
        for (int i = 0; i < size; i++) {
            result.append(arr[i]);
            if(i != size - 1){
                result.append(",");
            }
        }
        result.append("]");
        return result.toString();
        
    }
    
}

2. 自定义队列(MyQueue.java)

package com.BlueStarWei.queue;

/**
 * 开发终于到的问题:
 * 1. 元素poll完(元素实际上并没有从数组中删除,只是将头指针向后移)之后,再次添加数据的时候如何从头开始?
 *         判断queue有效的元素是否为空,如果为空,将头指针和尾指针重置到数组最前端
 * 
 * 优化:
 * 1. 与自定义数组列表相比,在创建队列的时候没有队列的类型为任意集合(E)类型,而是指定为Object[]类型,
 *         只有在元素返回时,返回为任意集合(E)类型
 *         
 * @author HuWei
 *
 * @param <E>
 */
public class MyQueue<E> {
    
    /**
     * The default capacity while use constructor form superClass
     */
    private final int DEFUALT_CAPACITY = 10;
    
    /**
     * The expending capacity while arr that is generated via constructor form superClass is full 
     */
    private final int ADD_CAPACITY = DEFUALT_CAPACITY / 2;
    
    /**
     * store the element
     */
    private Object[] queue;
    
    /**
     * the head pointer of queue
     *it always point the first alive element
     */
    private int front;
    
    /**
     * the end pointer of queue
     * it always point the last alive element
     */
    private int end;
    
    /**
     * the real size of queue
     */
    private int size;
    
    /**
     * check whether is the queue generated by constructor with initCapacity
     */
    private boolean hasInitCapacity;
    
    /**
     * generate a queue whose default size is DEFUALT_CAPACITY
     */
    public MyQueue() {
        queue = new Object[DEFUALT_CAPACITY];
        hasInitCapacity = false;
        end = -1;
    }
    
    /**
     * generate a queue whose default size is initCapacity
     */
    public MyQueue(int initCapacity){
        queue = new Object[initCapacity];
        hasInitCapacity = true;
        end = -1;
    }
    
    /**
     * store element to queue
     * @param element
     *         the element to be stored
     */
    public void push(E element){
        if(!hasInitCapacity && size == queue.length){
            Object[] queue2 = queue;
            queue = new Object[size + ADD_CAPACITY];
            for (int i = 0; i < queue2.length; i++) {
                queue[i] = queue2[i];
            }
        }
        queue[++end] = element;
        size++;
    }
    
    /**
     * remove the first alive element in queue
     * while queue is queue is empty, set front and end pointer point the queue's head 
     * 
     * @return
     *         the element to be remove
     */
    public E poll(){
        E element = (E)queue[front++];
        size--;
        if(isEmpty()){
            front = 0;
            end = -1;
        }
        return element;
    }
    
    /**
     * get the first alive element in queue
     * @return
     *         the element to be returned
     */
    public E peek(){
        E element = (E)queue[front];
        if(isEmpty()){
            element = null;
        }
        return element;
    }
    
    /**
     * check whether is queue empty.
     * 
     * @return
     * 
     */
    public boolean isEmpty(){
        if(size == 0){
            return true;
        }else {
            return false;
        }
    }
    
    /**
     * get the size of queue
     * 
     * @return
     *         the size of queue
     */
    public int size(){
        return size;
    }
}

  更多内容,请访问http://www.cnblogs.com/BlueStarWei

原文地址:https://www.cnblogs.com/BlueStarWei/p/7470744.html