自定义数组列表和队列

  最近一直在研究数据结构与算法,涉及到自定义数组和队列,感觉对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

时间: 2024-10-10 05:35:39

自定义数组列表和队列的相关文章

.NET重思(三)-数组列表与数组的区别,栈集合和队列结合的区别

数组列表和数组十分相似,区别在于数组列表的容量是可以动态变化的,而数组的容量是固定的.数组即Array类,数组列表即ArrayList类,两者十分相似.不过,Array类在System命名空间下,ArrayList类在System.Collections命名空间下.数组在初始化时需要指定容量,并且指定之后无法改变,而数组列表可以动态的改变容量. //初始化ArrayList ArrayList lst = new ArrayList(); //初始化ArrayList并将容量设置为100 Arr

Java中的自定义数组队列

在Java中,作为所有数据结构中存储和获取速度最快的一种,数组凭借其这种简单易用的优势在各个方面都能大显神威.但是数组也有自身的局限性.数组的长度必须是固定的一旦定义之后就无法动态的更改,这就会造成这样的问题,如果数组已满,就无法继续添加数据(当然你可以定义一个"足够大的数组",但问题是多大才是足够大呢?太小不够,太大浪费内存空间).如果删除一个数据,它的内存空间空着没有被使用.另外数组只能存储同一类型的数据,如果把它设置成Object类型的话,是可以存不同类型的数据了,但是设想这样一

C++ 运算符重载四(自定义数组类)

//自定义数组类 #include<iostream> using namespace std; //分析:能获取数组长度,添加元素,删除元素,修改元素 //要求重载[],=,==,!=运算符 class MyArray { private: int mLength; int* mSpace; public: MyArray(int length){ cout << "有参构造函数被调用了1" << endl; mLength = length; m

(转载)Android自定义标签列表控件LabelsView解析

Android自定义标签列表控件LabelsView解析 作者 donkingliang 关注 2017.03.15 20:59* 字数 759 阅读 406评论 0喜欢 3 无论是在移动端的App,还是在前端的网页,我们经常会看到下面这种标签的列表效果: 标签列表 标签从左到右摆放,一行显示不下时自动换行.这样的效果用Android源生的控件很不好实现,所以往往需要我们自己去自定义控件.我在开发中就遇到过几次要实现这样的标签列表效果,所以就自己写了个控件,放到我的GitHub,方便以后使用.有

队列篇之使用数组模拟一个队列

队列是一个有序列表, 可以使用数组实现, 也可以使用链表实现 队列遵守先进先出的原则 1. 下面使用数组模拟一个队列 public class ArrayQueueDemo { public static void main(String[] args) { ArrayQueue queue = new ArrayQueue(3); queue.add(1); queue.show(); System.out.println("-----------------"); queue.ad

数组与数组列表

数组 数组代表一系列对象或者基本数据类型,所有相同的类型都封装到一起——采用一个统一的标识符名称.简单来讲,数组就是一组相关数据的集合,是一连串的变量.Java中数组的定义和使用时通过方括号索引运算符进行的({}),一般来说,有两种定义数组的方法,只需在类型名或标识符后跟一对方括号即可. int[] a1; int a1[]; 两种表示方法是完全一样的.此时只是声明了指向数组的一个对象,并未对其分配任何空间,为了创建数组相应的存储空间,就必须要写一个初始化表达式.如: int b = {1, 2

自定义数组函数

// 自定义数组函数Array.prototype.maxima.//Array.prototype为必须的,maxima为数组名.//调用时arr.maxima()这样调用window.onload = function() { Array.prototype.sum = function(){ for(var sum = i = 0 ; i < this.length; i ++){ sum += parseInt(this[i]); } return sum; }; Array.proto

ArrayList数组列表

ArrayList数组列表 Collection接口和List接口的区别 List接口扩充了Collection接口,添加了索引相关的方法. code example Object get(int index) Object set(int index,Object element) int indexOf(Object elem) void add(int index,Object element) Object remove(int index) List接口中的大多数方法是基于索引的. A

泛型数组列表 ArrayList

为什么使用泛型数组列表而不使用普通数组? 1.普通数组经常会发生容量太大以致浪费的情况 2.普通数组无法动态更改数组 基本概念: 1.采用[类型参数]的[类]---->[泛型类] 2.[泛型类型]就是类型参数的类型 对泛型数组列表的操作: 1.添加元素,add方法,默认在尾部添加,变化参数可以插入到中间.删除元素 2.初始化容量(ensurecapacity或是把初始容量传递给构造器) 3.回收多余的存储空间(trimToSize) 4.访问数组元素 get(i) 5.转化为数组 toArray