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

Java中的自定义数组队列的更多相关文章

  1. Java中的5大队列,你知道几个?

    本文已收录至 https://github.com/vipstone/algorithm <算法图解>系列. 通过前面文章的学习<一文详解「队列」,手撸队列的3种方法!>我们知 ...

  2. 在Java中怎样把数组转换为ArrayList?

    翻译自:How to Convert Array to ArrayList in Java? 本文分析了Stack Overflow上最热门的的一个问题的答案,提问者获得了很多声望点,使得他得到了在S ...

  3. [转]Java中实现自定义的注解处理器

    Java中实现自定义的注解处理器(Annotation Processor) 置顶2016年07月25日 19:42:49 阅读数:9877 在之前的<简单实现ButterKnife的注解功能& ...

  4. Java中创建泛型数组

    Java中创建泛型数组 使用泛型时,我想很多人肯定尝试过如下的代码,去创建一个泛型数组 T[] array = new T[]; 当我们写出这样的代码时编译器会报Cannot create a gen ...

  5. Java中使用自定义类封装数组,添加类方法实现数据操作

    1.具体见注释 2.后续或有更新 public class MyArray { private long[] array; private int cnt; // 自定义数组类的元素个数 /** 使用 ...

  6. JAVA中常见的阻塞队列详解

    在之前的线程池的介绍中我们看到了很多阻塞队列,这篇文章我们主要来说说阻塞队列的事. 阻塞队列也就是 BlockingQueue ,这个类是一个接 口,同时继承了 Queue 接口,这两个接口都是在JD ...

  7. 浅谈Java中的Condition条件队列,手摸手带你实现一个阻塞队列!

    条件队列是什么?可能很多人和我一样答不出来,不过今天终于搞清楚了! 什么是条件队列 条件队列:当某个线程调用了wait方法,或者通过Condition对象调用了await相关方法,线程就会进入阻塞状态 ...

  8. Java中方法与数组

    1:方法(掌握) (1)方法:就是完成特定功能的代码块. 注意:在很多语言里面有函数的定义,而在Java中,函数被称为方法. (2)格式: 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参 ...

  9. JAVA中list,set,数组之间的转换详解

    JAVA的list,set,数组之间的转换,主要是使用Apache Jakarta Commons Collections,具体的方法如下:import org.apache.commons.coll ...

随机推荐

  1. eclipse:Workspace in use or cannot be created

    打开eclipse出现:Workspace in use or cannot be created, choose a different one 原因:出现这种情况一般是workspace的配置文件 ...

  2. Servlet--HttpServlet类

    HttpServlet类 定义 public class HttpServlet extends GenericServlet implements Serializable 这是一个抽象类,用来简化 ...

  3. LINUX读写文件区别

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  4. redis发布与订阅

    发布与订阅 除了实现任务队列外, Redis还提供了一组命令可以让开发者实现"发布/订阅"(publish/subscribe)模式. "发布/订阅"模式同样可 ...

  5. eclipse每次闪退后都提示查看\workspace\.metadata\.log

    错误如下: 找到<workspace>/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi"文件,将其删掉,再重启 ...

  6. [DeeplearningAI笔记]神经网络与深度学习4.深度神经网络

    觉得有用的话,欢迎一起讨论相互学习~Follow Me 4.2 深层神经网络中的前向传播 4.3 核对矩阵的维数 经验方法论 对于神经网络想增加得到没有bug的程序的概率的方法:需要仔细的思考矩阵的维 ...

  7. 本地工程引入maven工程的配置方式

    一.准备 IDE: IntelliJ IDEA 2016.3.1 maven: 3.5.2 JDK: 1.8 操作系统: Window 7 二.配置 1. maven 3.5 下载地址:http:// ...

  8. HTML5中的Web Notification桌面通知

    大家在做一些浏览器端的聊天功能的时候,或者在一些网站跟在线客服咨询的时候,会看到一些消息通知的提示,常见的有浏览器标签页的闪烁和屏幕右侧的消息通知.本篇博客就在这里简单的介绍一下如何实现这样的功能. ...

  9. Py3编码解码

    Py3编码解码   写的不好请谅解,有问题欢迎指出.   python2.x中的解决方案(图片来源于网络) #!/usr/bin/env python # -*- coding: utf-8 -*- ...

  10. SpringMVC源码情操陶冶-DispatcherServlet

    本文对springmvc核心类DispatcherServlet作下简单的向导,方便博主与读者查阅 DispatcherServlet-继承关系 分析DispatcherServlet的继承关系以及主 ...