作者:Flyingis
數組是Java語言內置的類型,除此之外,Java有多種保存對象引用的方式。Java類庫提供了一套相當完整的容器類,使用這些類的方法可以保存和操縱對象。下面分別進行討論,在研究Java容器類之前,先了解一下Java數組的基本功能和特性。
1. 數組的基本特性
數組與其它種類的容器(List/Set/Map)之間的區別在于效率、確定的類型和保存基本類型數據的能力。數組是一種高效的存儲和隨機訪問對象引用序列的方式,使用數組可以快速的訪問數組中的元素。但是當創建一個數組對象(注意和對象數組的區別)后,數組的大小也就固定了,當數組空間不足的時候就再創建一個新的數組,把舊的數組中所有的引用復制到新的數組中。
Java中的數組和容器都需要進行邊界檢查,如果越界就會得到一個RuntimeException異常。這點和C++中有所不同,C++中vector的操作符[]不會做邊界檢查,這在速度上會有一定的提高,Java的數組和容器會因為時刻存在的邊界檢查帶來一些性能上的開銷。
Java中通用的容器類不會以具體的類型來處理對象,容器中的對象都是以Object類型處理的,這是Java中所有類的基類。另外,數組可以保存基本類型,而容器不能,它只能保存任意的Java對象。
一般情況下,考慮到效率與類型檢查,應該盡可能考慮使用數組。如果要解決一般化的問題,數組可能會受到一些限制,這時可以使用Java提供的容器類。
2. 操作數組的實用功能
在java.util.Arrays類中,有許多static靜態方法,提供了操作數組的一些基本功能:
equals()方法----用于比較兩個數組是否相等,相等的條件是兩個數組的元素個數必須相等,并且對應位置的元素也相等。
fill()方法----用以某個值填充整個數組,這個方法有點笨。
asList()方法----接受任意的數組為參數,將其轉變為List容器。
binarySearch()方法----用于在已經排序的數組中查找元素,需要注意的是必須是已經排序過的數組。當Arrays.binarySearch()找到了查找目標時,該方法將返回一個等于或大于0的值,否則將返回一個負值,表示在該數組目前的排序狀態下此目標元素所應該插入的位置。負值的計算公式是“-x-1”。x指的是第一個大于查找對象的元素在數組中的位置,如果數組中所有的元素都小于要查找的對象,則x = a.size()。如果數組中包含重復的元素,則無法保證找到的是哪一個元素,如果需要對沒有重復元素的數組排序,可以使用TreeSet或者LinkedHashSet。另外,如果使用Comparator排序了某個對象數組,在使用該方法時必須提供同樣的Comparator類型的參數。需要注意的是,基本類型數組無法使用Comparator進行排序。
sort()方法----對數組進行升序排序。
在Java標準類庫中,另有static方法System.arraycopy()用來復制數組,它針對所有類型做了重載。
3. 數組的排序
在Java1.0和1.1兩個版本中,類庫缺少基本的算法操作,包括排序的操作,Java2對此進行了改善。在進行排序的操作時,需要根據對象的實際類型執行比較操作,如果為每種不同的類型各自編寫一個不同的排序方法,將會使得代碼很難被復用。一般的程序設計目標應是“將保持不變的事物與會發改變的事物相分離”。在這里,不變的是通用的排序算法,變化的是各種對象相互比較的方式。
Java有兩種方式來實現比較的功能,一種是實現java.lang.Comparable接口,該接口只有一個compareTo()方法,并以一個Object類為參數,如果當前對象小于參數則返回負值,如果相等返回零,如果當前對象大于參數則返回正值。另一種比較方法是采用策略(strategy)設計模式,將會發生變化的代碼封裝在它自己的類(策略對象)中,再將策略對象交給保持不變的代碼中,后者使用此策略實現它的算法。因此,可以為不同的比較方式生成不同的對象,將它們用在同樣的排序程序中。在此情況下,通過定義一個實現了Comparator接口的類而創建了一個策略,這個策略類有compare()和equals()兩個方法,一般情況下實現compare()方法即可。
使用上述兩種方法即可對任意基本類型的數組進行排序,也可以對任意的對象數組進行排序。再提示一遍,基本類型數組無法使用Comparator進行排序。
Java標準類庫中的排序算法針對排序的類型進行了優化——針對基本類型設計了“快速排序”,針對對象設計的“穩定歸并排序”。一般不用擔心其性能。
其它相關內容:
Java容器分析--List和Set
Java容器分析--Map