队列和队列重绘
自定义队列:
在谈自定义队列之前,我们要清楚一个问题就是------“数组”的优点和缺点有哪些,优点当然有很多,但是,当我们所需要存储的数据元素个数不定时能用数组来存储吗?不行!当我们需要存储的对象类型不定或者有多种类型的时候能用到数组吗?不行!这个时候就需要自定义队列啦!
自定义队列的思路:
首先在实现类的内部还是使用数组来保存装入队列的对象,每次新加入对象时,则再创建一个比原来数组长度大1的数组,再将新数组的地址赋给原来的数组,这样就可以想存多少就存多少啦!我们来通过下面的例子来说明:
//实例化一个学生对象的数组 arr[],长度为0 ,Student是已经创建的一个学生类 private Student[] arr=new Student[0];
//定义一个size属性,用来表示队列中的元素个数
private int size=0;
/**
* 添加一个新元素,参数stu是要被储存的对象
*/
public void add(Student stu){
//实例化一个新的数组,数组长度是原来数组长度+1
Student[] stud=new Student[arr.length+1];
//将原数组中的数据放到新数组中去
for(int i=0;i<arr.length;i++){
stud[i]=arr[i];
}
//将要新加的元素stu加到新数组stud的后面
stud[arr.length]=stu;
//将新数组的首地址赋给原数组
arr=stud;
size++;
}
以上就是自定义队列的用法啦!
那么当我们存储的类型时多种类型时,又应该在怎样做呢?
别忘了java中所有引用数据类型的父类是Object,那么我们在定义数组类型的时候将它定义成Object类型,然后每个方法指定的类型也为Object就行啦!
这里我们容易想到另一个问题,要是我要数组有时只存一种数据类型有时又要存多种数据类型,又该怎么存呢?
这个时候我们就要用到传说中的“泛型”了。泛型----是实用一个E来表示的(注意!这里的E只表示类,不能用来表示基本数据类型(8大基本数据类型))如果想在使用了泛型的队列中存储8大基本类型的值,可以使用它们各自的封装类(在java.lang.*中都可以找到),下面我们来看一个使用泛型的例子:
public class Queue<E> {
//实例化一个数组 arr[],长度为0
private Object [] arr=new Object[0];
//定义一个size属性,用来表示队列中的元素个数
private int size=0;
/**
* 添加一个新元素,参数e是要被储存的对象
*/
public void add(E e){
//实例化一个新的数组,数组长度是原来数组长度+1
Object[] tempArray =new Object[arr.length+1];
//将原数组中的数据放到新数组中去
for(int i=0;i<arr.length;i++){
tempArray[i]=arr[i];
}
//将要新加的元素e加到新数组tempArray的后面
tempArray[arr.length]=e;
//将新数组的首地址赋给原数组
arr=tempArray;
size++;
}
注意:当我们用要指定其为某种格式时,格式应该是:
private static Queue<Shape> qd = new Queue<Shape>();//Queue指定为Shape型,实例化一个队列qd的对象
相信大家看了上面的例子,“泛型”这个东东其实不抽象吧。
队列重绘:
理解了自定义队列后,队列的重绘操作也就简单啦!我们还是先来看看在画图板中实用数组进行重绘时的操作:
//创建一个画布面板panelC
JPanel panelC = new JPanel(){
//重写panel中的重绘方法,g是画布
public void paint(Graphics g){
//先调用父类中的paint方法,系统式自动设置其父类为Object,
不用我们手动继承
super.paint(g);
//将监听器中获得到图像的像素点坐标(x,y)赋给二维数组arr[][]
int arr[][]=ButtonLitener.getArr();
if(arr!=null){
//通过循环取得数组中的坐标点
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
//通过Color对象将像素点转换成对应的颜色
Color color=new Color(arr[i][j]);
//调用setColor方法,给画布添加颜色
g.setColor(color);
//调用drawLine方法绘制点,因为图像实际上是由点组成的,
注意画的是点,所以画直线的起始坐标和终点坐标是一样的
g.drawLine(i, j, i, j);
}
}
}
}
};
如果我们使用队列重绘就不用这样写啦!因为实际上我们在用数组进行重绘时,是存储了整个画布,但如果使用自定义队列,因为自定义队列有长度可以随增的优点,我们可以只存我们画的单个图像,而不用存整个画布了。
那么 为什么可以用队列来实现画图板的重绘呢?还是先来看看代码:
//创建一个画布面板
JPanel panelC = new JPanel(){
//重写父类的paint方法
public void paint(Graphics g){
//先调用父类的paint方法
super.paint(g);
//创建一个shape类型的队列(队列使用的是泛型),
得到监听器中用来存放我们画的图形的队列
Queue<Shape> qd=ButtonLitener.getQ();
//循环取得队列中存放的每一个shape
for(int i=0;i<qd.getSize();i++){
Shape shape=qd.get(i);
//通过调用draw方法将图重新画出来
shape.draw((Graphics2D) g);
}
看完代码后,如果你知道用数组来对画图板进行重绘的原理就不难理解用队列来重绘画图板了,因为在数组中我们存放的是画图面板的每个像素点,再通过遍历每个坐标来重新绘制画图板,而用队列实现重绘时,队列里面实际上存放的是每个Shape对象,这里所说的shape是一个抽象类,它的构造方法是:
//声明起始点坐标x1
private int x1;
// 声明起始点坐标y1
private int y1;
// 声明结束点坐标x2
private int x2;
// 声明结束点坐标y2
private int y2;
// 声明设置线条粗细的对象
private Stroke stroke;
// 声明设置颜色的属性
private Color color;
public Shape(int x1, int y1, int x2, int y2, Color color,Stroke stroke) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.stroke = stroke;
this.color=color;
}
当然,要完成画图板的重绘操作光靠这些是不行的,我们必须在监听器中运用队列或者是数组来存放我们画的图像,只不过用自定义队列来存放的话会给我们带来很大的方便。后面附上了用队列对画图板进行重绘的代码,希望大家多多提出好的建议呀!
分享到:
相关推荐
开发者可以根据具体需求选择合适的数据结构和实现方式。例如,如果需要高效访问元素,可以选择ArrayList实现的顺序队列;如果频繁进行插入和删除操作,LinkedList更适合;如果内存有限,循环队列可以有效利用空间。 ...
总结,"tp5.1消息队列 think-queue" 是一种在ThinkPHP5.1环境中实现消息队列的方式,通过使用think-queue组件,开发者可以轻松地创建和管理异步任务,提高应用的并发处理能力和系统稳定性。理解其安装、配置、使用...
- 采用队头/队尾间隔至少一个空闲元素的方法实现循环队列,这样可以避免队列的物理连续性与逻辑连续性的混淆,同时便于检测队列是否为空或满。 - 当队列为满时尝试执行入队操作,或者队列为时空执行出队操作时,...
循环队列是一种特殊的队列,它在队列的两端都可以进行插入和删除操作,通过对循环队列的基本操作和应用,我们可以更好地理解和掌握数据结构的概念。 循环队列的基本操作 循环队列的基本操作包括构造、清空、销毁、...
### 数据结构——队列的应用与C语言实现 #### 背景介绍 本文将通过一个经典的算法问题“农夫过河”来探讨队列在实际编程中的应用,并使用C语言进行实现。这个问题不仅考验对数据结构的理解,还涉及到位运算等计算机...
### 数据结构:队列实现详解 #### 一、队列概念与特性 在计算机科学领域,**队列**是一种常见的线性数据...通过以上步骤,我们可以清楚地看到队列的各种操作是如何实现的,这有助于深入理解和掌握队列这种数据结构。
它通过将任务放入队列中,然后由一个或多个工作线程按顺序取出并执行,有效地实现了任务的异步处理和调度。下面将详细讨论如何实现C#任务队列及其相关知识点。 1. **线程安全**: - 在多线程环境下,对任务队列的...
在这个问题中,我们将探讨如何使用数据结构中的队列来解决...通过创建`Node`类表示舞者,并定义`Queue`类实现队列操作,我们可以有效地管理和配对舞者。这种方法尤其适用于处理动态变化的舞者数量,且易于扩展和理解。
总之,`PriorityQ.java`文件可能是一个简单的数组实现优先队列的示例,通过分析这个文件,我们可以学习到如何利用数组数据结构实现优先队列,以及理解其核心的插入、删除和查找操作。同时,这也能帮助我们更好地掌握...
### 栈和队列的基本操作实现及其应用 #### 一、实验目的 1. **熟练掌握栈和队列的基本操作**:本实验旨在使学生熟悉并掌握栈和队列这两种基本的数据结构,并能够在其常见的存储结构(即链式存储和顺序存储)上实现...
消息队列提供了线程间的同步和通信能力,是rt-thread系统中实现并发和协作的重要工具。它适用于那些需要将数据结构从一个任务传递到另一个任务的情况,尤其适用于数据量小且传输频繁的应用场景。 总之,rt-thread的...
为了实现循环,我们需要在进行进队和出队操作时处理边界条件,例如队头等于队尾时,并不意味着队列为空,而可能是满或者空,这取决于具体实现的策略。 5. **模板类的定义**:在C++中,定义一个循环队列的模板类可能...
以下是一个简单的C语言实现链队列的示例: ```c #include #include // 定义链队列节点 typedef struct Node { int data; struct Node* next; } Node; // 队列结构体 typedef struct Queue { Node* front; ...
### C语言实现链式队列的基本操作 #### 一、链式队列简介 链式队列是一种基于链表的数据结构,它具有队列的基本特性,即...通过对这些基本操作的理解和实现,可以帮助开发者更好地掌握链式队列的应用场景和技术细节。
本实验“数据结构队列和栈的模板实验”着重于使用模板实现这些数据结构,以实现对不同类型数据的通用处理。 1. **队列**: - **定义**:队列是一种先进先出(FIFO,First In First Out)的数据结构,元素在队列的...
链队列是一种基于链式结构实现的队列数据结构,其特点是存储空间可以在运行时动态扩展,不局限于预先设定的固定大小。在本题中,我们需要实现四个基本操作:初始化队列、入队列、出队列以及销毁队列。下面将详细讲解...
在这个“用消息队列实现的简单聊天程序”中,我们可以探讨以下几个关键知识点: 1. **消息队列的概念**:消息队列是一种存储和转发的机制,它在不同的进程或系统之间作为数据传输的桥梁。当一个进程生成消息时,它...
在本项目中,我们探讨的是如何使用Microsoft的Visual C++(VC++)集成开发环境和MFC(Microsoft Foundation Classes)库来构建一个简单的画图板应用程序。MFC是微软提供的一套C++类库,用于简化Windows应用程序的开发,...
数据结构-实验4-循环队列的实现和运算.doc