数组队列的实现

1.什么是数组队列

要知道这个问题,首先我们要清楚数组有哪些特点。
数组的优点是显而易见的,但是数组有哪些缺点呢?
其中我认为最大的一个缺点就是数组大小固定,如果要存储的数据个数不确定的时候?就可能出现以下两种情况:
1.数组空间不够,导致越界异常发生
2.如果空间太大了,数据不够,就会浪费内存空间
那如何解决这个问题呢,或许数组队列可以很好的解决这个问题。

2队列的简单实现

我们先实现一个简单的队列,这个队列能解决的问题就是数组大小固定这个问题。我们以学生信息管理为例:
首先我们需要一个学生类;

/* 定义Student学生类 */
public class Student {	
/*定义学生的四个属性*/
	public int score;
	protected char sex;
	int age;
	private String name;

	public Student(int score, char sex, int age, String name) {
		this.score = score;
		this.sex = sex;
		this.age = age;
		this.name = name;
	}

	public String toString() {
		return "姓名:" + name + "\t年龄:" + age + "\t性别:" + sex + "\tr学分:" + score;
	}

	// 如果属性的访问修饰符不是public,则要给属性定义public的get和set方法
	// 定义设置姓名属性值的方法
	public void setName(String n) {
		name = n;
	}

	// 定义获取姓名属性值的方法
	public String getName() {
		return name;
	}
	// 省略了sex和age的get和set方法。
	}

这样我们一个学生类就定义好了。然后我们就要实现队列,看下面代码:

public class ArrayList {	
	private Student [] array = null; //声明学生类型的数组名属性	
	private int size = 0;   //声明记录数组队列中存储的元素个数属性
	/**
	 * 构造方法
	 */
	public ArrayList() {
		array = new Student [0];// 实例化数组对象,长度为0
	}
	/**
	 * 构造方法
	 * @param length要创建新数组的大小
	 */
	public ArrayList(int length) {
		array = new Student[length];// 实例化数组对象,长度为length
	}
	
	/**
	 * 实现add方法,向队列中加入一个学生对象
	 */
	public void add(Student stu) {
		// 判断数组长度是否为0或者数组中已经存满数据
		if (array.length == 0 || array.length == size) {
			// 创建一个新的数组对象,长度array数组的长度+1
		Student[] newArray = new Student[array.length + 1];
			// 把array数组中的数据存入newArray数组中
			for (int i = 0; i < array.length; i++) {
				newArray[i] = array[i];
			}
			array = newArray;// 交换首地址,指向新建的数组
		}
		array[size++] = stu;// 将数据存入到array数组中
	}
	
	/**
	 * 获取指定索引位置的数据 
	 * @param index要获取索引位置的数据
	 * @return 返回对应索引位置的数据,如果index越界则返回null。
	 */
	public Student get(int index) {
		if (index < 0 || index >= size)
			return null;
		return array[index];
	}
	
	/**
	 * 获取数组队列中存储的元素总数
	 * @return 返回size属性值
	 */
	public int size() {
		return size;
	}		
}

这样一个简单队列的实现就完成了,这个队列能在学生个数不确定情况下,存储学生的数据。接下来就是我们就要测试一下这个队列了:

import java.util.Random;
public class Manage {
	public static void main(String[] args) {
		ArrayList mal = new ArrayList(10);
		Random rand = new Random();
		int size = rand.nextInt(59)+1;//随机产生一个0到60的数
		for (int i = 0; i < size; i++) {
			Student stu = new Student(rand.nextInt(100), rand.nextInt(2) == 0 ? '男' : '女', 
			rand.nextInt(10) + 17,"姓名" + ((char) (rand.nextInt(26) + 65)));
			mal.add(stu);
		}//创建学生对象,并给对象赋初值,并且保存到数组队列中
		
		/**
		 * 打印队列中每个学生对象的信息
		 */
		System.out.println(mal.size()+"个学生信息如下:");
		for (int i = 0; i < mal.size(); i++) {
			Student stu = mal.get(i);//调用get方法,得到队列中指定位置的数据
			System.out.println(stu.toString());//输出指定位置的数据		
	}	
  }	
}		

运行结果:
在这里插入图片描述

3队列的简单完善(泛型)

上面的队列最大的缺点就是,只能放入Student类(或其子类)的对象,这就很麻烦了,因为如果我们要存储其他的对象的时候,我们又要重新创建一个队列。对于这种问题,java中的"泛型"语法就能很好的解决这个问题。首先我们需要改变队列的定义,并可以将Student对象换成Object,并将所有的引用数据类型用代替。

泛型的特点:

(1)泛型(、<K、V>、、…) 不是Java中的一种数据类型。只是一个特殊的符号,可以在你不确定要存储什么类型的数据时,用这个符号代替Java中所有的数据类型。
(2)当你使用的时候,你可以用对应的数据类型来代替这个符号,这样就只能存储你指定的这一种数据类型;如果你不指定,则任意一种数据类型都可以存储。

看下面代码:
先定义一个Teacher类

public class Teacher {
	public String name;
	public Teacher(String name) {
		this.name = name;
	}
	public String toString() {
		return "老师" + name;
	}
}

队列中的实现(注意泛型的使用):

public class ArrayList<E> { // <E>声明数组队列支持泛型
	
	private Object [] array = null; //声明Obeject类型的数组名属性
	
	private int size = 0;   //声明记录数组队列中存储的元素个数属性
	
	/**
	 * 构造方法
	 */
	public ArrayList() {
		array = new Object [0];// 实例化数组对象,长度为0
	}

	/**
	 * 构造方法
	 * @param length要创建新数组的大小
	 */
	public ArrayList(int length) {
		array = new Object[length];// 实例化数组对象,长度为length
	}
	
	/**
	 * 实现add方法,向队列中加入一个指定类型的对象
	 */
	public void add(E stu) {
		// 判断数组长度是否为0或者数组中已经存满数据
		if (array.length == 0 || array.length == size) {
			// 创建一个新的数组对象,长度array数组的长度+1
		Object [] newArray = new Object [array.length + 1];
			// 把array数组中的数据存入newArray数组中
			for (int i = 0; i < array.length; i++) {
				newArray[i] = array[i];
			}
			array = newArray;// 交换首地址,指向新建的数组
		}
		array[size++] = stu;// 将数据存入到array数组中
	}
	
	/**
	 * 获取指定索引位置的数据 
	 * @param index要获取索引位置的数据
	 * @return 返回对应索引位置的数据,如果index越界则返回null。
	 */
	public E get(int index) {
		if (index < 0 || index >= size)
			return null;
		return (E) array[index];
	}
	
	/**
	 * 获取数组队列中存储的元素总数
	 * @return 返回size属性值
	 */
	public int size() {
		return size;
	}	
}

接下来测试一下这个队列能不能存两个不同对象的信息:

import java.util.Random;
public class Manage {

	public static void main(String[] args) {
      //创建队列对象:只能放入Student类型对象的队列
		ArrayList<Student> mal = new ArrayList<Student>(10);
		Random rand = new Random();
		int size = rand.nextInt(59)+1;//随机产生一个0到60的数
		for (int i = 0; i < size; i++) {
			Student stu = new Student(rand.nextInt(100), rand.nextInt(2) == 0 ? '男' : '女', 
			rand.nextInt(10) + 17,"姓名" + ((char) (rand.nextInt(26) + 65)));
			mal.add(stu);
		}	
		/**
		 * 打印队列中每个学生对象的信息
		 */
		System.out.println(mal.size()+"个学生信息如下:");
		for (int i = 0; i < mal.size(); i++) {
			Student stu = mal.get(i);//调用get方法,得到队列中指定位置的数据
			System.out.println(stu.toString());//输出指定位置的数据
		}		
	//创建队列对象:只能放入Teacher类型对象的队列
			ArrayList<Teacher> altc = new ArrayList<Teacher>(10);
			int s = rand.nextInt(19)+1;//随机产生一个0到20的数
			for (int j = 0; j < s; j++) {
				Teacher teac = new Teacher("姓名" +((char) (rand.nextInt(26) + 65)));
				altc.add(teac);
			}	
			/* 打印队列中每个学生对象的信息*/
	System.out.println(altc.size()+"个老师信息如下:");
			for (int i = 0; i <altc.size(); i++) {
				Teacher teac = altc.get(i);//调用get方法,得到队列中指定位置的数据
				System.out.println(teac.toString());//输出指定位置的数据
    }
  }			
}		

代码运行结果:
在这里插入图片描述
这样一个简单的队列基本就完成了,不过这个队列还有许多的不足之处有待完善,首先,没加入一个对象,都要创建一个数组,能不能多预留一些空间,预留多少空间呢?另外我们如何对队列中指定位置的数据进行插入和删除等等。这些都是我们可以进一步优化这个队列的地方。

猜你喜欢

转载自blog.csdn.net/weixin_44307764/article/details/86660560