隊列和隊列重繪
自定義隊列:
在談自定義隊列之前,我們要清楚一個問題就是------“數組”的優點和缺點有哪些,優點當然有很多,但是,當我們所需要存儲的資料元素個數不定時能用數組來存儲嗎?不行!當我們需要存儲的對象類型不定或者有多種類型的時候能用到數組嗎?不行!這個時候就需要自定義隊列啦!
自定義隊列的思路:
首先在實作類的内部還是使用數組來儲存裝入隊列的對象,每次新加入對象時,則再建立一個比原來數組長度大1的數組,再将新數組的位址賦給原來的數組,這樣就可以想存多少就存多少啦!我們來通過下面的例子來說明:
[/code]
//執行個體化一個學生對象的數組 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.*中都可以找到),下面我們來看一個使用泛型的例子:
[code="java"]
public class Queue<E> {
//執行個體化一個數組 arr[],長度為0
private Object [] arr=new Object[0];
//定義一個size屬性,用來表示隊列中的元素個數
private int size=0;
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的對象
相信大家看了上面的例子,“泛型”這個東東其實不抽象吧。
隊列重繪:
了解了自定義隊列後,隊列的重繪操作也就簡單啦!我們還是先來看看在畫圖闆中實用數組進行重繪時的操作:
[code="java"][/code]
//建立一個畫布面闆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;
}
當然,要完成畫圖闆的重繪操作光靠這些是不行的,我們必須在監聽器中運用隊列或者是數組來存放我們畫的圖像,隻不過用自定義隊列來存放的話會給我們帶來很大的友善。後面附上了用隊列對畫圖闆進行重繪的代碼,希望大家多多提出好的建議呀!