专注Java教育14年 全国咨询/投诉热线:444-1124-454
星辉LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 详解自定义数组队列

详解自定义数组队列

更新时间:2021-01-04 08:46:27 来源:星辉 浏览1147次

数组作为所有数据结构中存储和获取速度最快的一种,凭借其独特的优势在数据存储领域独领风骚。但是数组也有其自身的局限性,造成了一些不可避免的问题。我们都知道数组的长度必须是固定的,且一旦定义之后就无法动态的更改,这就会造成这样的问题,如果数组已满,就无法继续添加数据。为了解决这个问题,人们想到了自定义数组队列的方法。

 

试想一下,如果删除一个数据,它的内存空间空着没有被使用。另外数组只能存储同一类型的数据,如果把它设置成Object类型的话,是可以存不同类型的数据了,但是设想这样一种情况:现在项目中有定义了一个Object类型的数组。项目中拥有很多的图形类,确实这个数组都能保存,但问题是这时用户保存了一个其他类型的东西,程序是不会报错的,因为类型是Object。这样肯定是不行的。另外在Java中向上转型是安全的,Object类型可以适应一切类型,但是向下转型确是不安全的。比如下面的代码:

package Cbs;

public class Test {

 

public static void main(String[] args) {

//定义Object类型的数组

Object[] array=new Object[10];

//使用基本数据类型的包装类

Integer i=10;

Float f=12.0f;

//向上转型,没有问题

array[0]=i;

array[1]=f;

//向下转型

int i1=(int)array[0];

//注意array[1]中存储的是12.0,但是这样子语法没有问题,编译不会出错

int i2=(int)array[1];

System.out.println(i1);

System.out.println(i2);//抛出ClassCastException异常

}

 

}

 

也就是说,如果使用这样的数组,在转型是发生问题是很难发现的。这也是数组的一个局限性。那么既然数组存在这样的缺陷,我们就要想办法解决这个问题。该如何解决呢?数组长度当然是无法发生变化的,但是数组名里面存储的是数组在内存中的首地址这个确是可以改变的。那么是否可以通过地址的改变来动态改变数组的大小呢?答案是肯定的。我们可以声明一个新的数组,把它的大小增加到我们想要的程度,然后把原数组的值copy到新数组中,再把新数组赋值给原数组,这样操作就可以使得数组的大小发生动态改变了。这时增加一个数据就让新数组长度加一,减少一个数据,就让新数组长度减一就可以了。数组长度的问题就解决了。那么数据类型应该如何解决呢?这就要使用Java的泛型搞定了。泛型Java中并不是一种数据类型,而是一个用于表示类型的符号,常用的泛型表示符号有E、K、Y等。这样我们在定义类的时候就可以指定泛型,然后在类中使用指定的类型返回和输入,这样就不会产生类型的问题了。下面要做的就是定义一个类,用于操作数组,也就是我们要讲的自定义数组队列。

package com.cbs;

 

/**

 * 自定义数组队列

 * @author CBS

 */

 

public class MyList<E> {//使用泛型E

//声明一个Object数组

private Object[] array;

private int size=0;//记录队列中数据类型的长度

private int initCount=0;//初始化时数组的大小,默认为0

private int incresCount=1;//数组已满时,每次数组的增长长度

/**

 * 构造方法

 * @param initCount 为数组的初始长度

 */

public MyList(int initCount){

this.initCount=initCount;

array=new Object[initCount];

}

/**

 * 构造方法

 * @param initCount 为数组的初始长度

 * @param incresCount 为数组满是每次的增长长度

 */

public MyList(int initCount, int incresCount) {

this.initCount = initCount;

this.incresCount = incresCount;

array=new Object[initCount];

}

 

//实现数据的添加

public void add(E e){

if(size<initCount){

array[size]=e;

}

else{

Object[] newArray=new Object[array.length+incresCount];

newArray[size]=e;

for(int i=0;i<array.length;i++){

newArray[i]=array[i];

}

initCount+=incresCount;

array=newArray;

}

size++;

}

//实现删除指定下标位置的数据

public void delete(int i){

size--;

initCount--;

Object[] newArray=new Object[array.length-1];

for(int j=0;j<i;j++)

newArray[j]=array[j];

for(int j=i+1;j<array.length;j++)

newArray[j-1]=array[j];

array=newArray;

}

//实现插入指定下标位置的数据

public void insert(E e,int i){

if(size<initCount && i>=0 && i<size-1){

for(int j=size;j>i;j--)

array[j]=array[j-1];

array[i]=e;

}

else{

Object[] newArray=new Object[array.length+incresCount];

for(int j=0;j<array.length;j++){

newArray[j]=array[j];

}

initCount+=incresCount;

array=newArray;

for(int j=size;j>i;j--)

array[j]=array[j-1];

array[i]=e;

}

size++;

}

//实现获取指定下标位置的数据

public E get(int i){

if(i<0 || i>=size)

return null;

else

return (E) array[i];

}

//实现更新指定下标位置的数据

public void upDate(E e,int i){

if(i>=0 && i<size)

array[i]=e;

}

//获取数组队列中存储的元素个数

public int legnth(){

return size;

}

 

}

 

通过上面的代码,我们完成了一个自定义数组队列。当然这里对自定义数组队列做了一定的优化,可以由用户指定初始的队列长度和每次队满时增长的长度。相比于上面所说的每次长度加一,这样做就不用每次都新建一个新的数组了。这样以后只要在类中实例化MyList的对象就可以很方便的操作数组队列啦。在学习数据结构的过程中我们难免遇到这样那样的问题,但是数学领域的学者们总是能想到解决的办法,我们也是站在了他们的肩膀上才能学到这么多优质的知识。兴趣才是我们学习的根本动力,对数据结构感兴趣的小伙伴在本站的数据结构和算法教程中还有着许多有趣的数据结构知识等你来学哦。


提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>