/**
* 示範資料類型封裝和泛型類必要性
*/
package seek;
/**
*設計一個已排序的對象數組類,實現尋找的演算法:
*本例示範使用Comparable介面及實現該介面的類,示範資料類型封裝類和泛型類必要性。
*本例希望設計一個已排序的對象數組類SortedArray,該類能夠在一個數組中按順序儲存一個類的多個對象,不限定
*數組元素所屬的類,如果Integer或String類都可以,並能夠實現在數組中尋找指定對象的功能。
*
*/
public class SortedArray<T>{
private Comparable table[]; //存放實現Comparable介面對象
private int count;
public SortedArray(int n)
{
if(n<=0) n=10;
this.table=new Comparable[n];
this.count=0;
}
public void print() //輸出數組元素
{
System.out.print("table: " );
for(int i=0;i<this.count;i++)
System.out.print(" " +table[i].toString());
System.out.println();
}
public int search(T tobj) //順序尋找
{
int i=0;
while(i<this.count&&!this.table[i].equals(tobj)) //比較兩個對象是否相等
i++;
if(i<this.count) //尋找成功
return i+1; //下標轉換成序號
else
return -1; //尋找失敗
}
public boolean insert(T tobj) //將元素按升序插入數組
{
if(this.count<this.table.length && tobj instanceof Comparable ) //數組未滿且tobj是實現Comparable介面對象時
{
int i=0;
Comparable cmpobj=(Comparable)tobj;
while(i<this.count && cmpobj.compareTo(this.table[i])>=0) //比較兩個對象的大小
i++;
for(int j=this.count-1;j>=i;j--) //若干元素向後移動
table[j+1]=table[j];
this.table[i]=cmpobj; //插入
this.count++;
return true; //插入成功
}
else
return false; //插入未成功
}
}
package study;
import seek.SortedArray;
class SortedArray_ex {
public static void main(String[] args) {
SortedArray<Integer>sal1=new SortedArray<Integer>(10);
Integer intobj=new Integer(2);
sal1.insert(intobj);
intobj=new Integer(3);
sal1.insert(intobj);
intobj=new Integer(1);
sal1.insert(intobj);
sal1.print();
SortedArray<String>sa2=new SortedArray<String>(10);
String strobj=new String("xyz");
sa2.insert(strobj);
strobj=new String("aaa");
sa2.insert(strobj);
strobj=new String("abc");
sa2.insert(strobj);
sa2.print();
System.out.println("search "+strobj.toString()+": "+sa2.search(strobj));
}
}
]程式設計說明如下:
1〉數組元素的通用性設計:
為了設計一個通用的對象數組,使它具有適用於多個類的操作(如順序儲存或尋找),則數組元素所屬的類可能有多種,在編譯時間不能確定,需要在運行時確定。通常做法是聲明數組元素為Object類,例如:
private Object table[];
根據子類對象即時父類對象的原則,程式運行時,數組元素table[i]可以賦值為任何類型的對象。
上述聲明對於本例則不行,因為數組元素table[i]是Object類對象,它只能調用Object類方法,而Object類只有equals()方法,沒有compareTo()比較方法,對象之間比較是否相等,不能比較值的大小,因而不能實現排序功能。所以,本例聲明數組元素類型為Comparable,它能夠複製為實現Comparable介面的類的對象。聲明如下:
private Comparable table[]; //存放實現Comparable介面對象
2〉使用Integer對象的必要性:
本例希望數組元素或者是整數,或者是字元集。為了程式的通用性,以將數組元素的型別宣告為Comparable,數組中只能存放對象,而不能存放整數值,因此必須將整數值構造成對應的Integer對象存放數組,這體現了java聲明基礎資料型別 (Elementary Data Type)封裝類的意義。
3〉使用泛型類與否的差別:
本例希望一個數組儲存同一個類的多個對象,或者是Integer對象,或者是String類對象,必須在同一個類的對象進行比較,實現尋找和排序演算法,而不同類的對象之間進行比較沒有實際意義。
Integer和String類都是實現了Comparable介面中的compareTo()方法。兩個類的方法分別聲明如下:
public int compareTo(Integer anotherInteger) //Integer類
public int compareTo(String anotherString) //String類
因此,不同類之間對象進行比較則會產生執行階段錯誤。
如果SortedArray類不聲明為泛型類,如:
public class SortedArray
則SortedArray類對象sa1中可以混合存放Integer和String等實現了comparable介面的類的對象。但是當插入一個對象時,採用comparaTo()方法將Integer與String類對象比較,則運行時產生錯誤。
將SortedArray類聲明為泛型類後,在建立對象時,必須確定該類參數為另一個類,如:
SortedArray<Integer>sa1=new SortedArray<Integer>(10);
此時,在sa1中插入Integer對象,如果插入一個字串對象,則編譯時間產生錯誤。
所以,對於本例而言,聲明泛型類能夠確保一個數組中的所有元素是同一個類的對象。而且採用泛型類將運行時的類型檢查提前到編譯時間進行,使代碼更安全。
累死我了,打這麼字!