1. 程式人生 > >java 物件的集合

java 物件的集合

一 、 陣列:

陣列(array)是相同型別變數的集合,可以使用共同的名字引用它。陣列可被定義為任何型別,可以是一維或多維。陣列中的一個特別要素是通過下標來訪問它。陣列提供了一種將有聯絡的資訊分組的便利方法。

注意:如果你熟悉C/C++,請注意, Java陣列的工作原理與它們不同。

1、陣列不是集合,它只能儲存同種型別的多個原始型別或者物件的引用。陣列儲存的僅僅是物件的引用,而不是物件本身。

2、陣列本身就是物件,Java中物件是在堆中的,因此陣列無論儲存原始型別還是其他物件型別,陣列物件本身是在堆中的。

3、陣列宣告的兩種形式:一、int[] arr; 二、int arr[]; 推薦使用前者,這符合Sun的命名規範,而且容易瞭解到關鍵點,這是一個int陣列物件,而不是一個int原始型別。

4、在陣列宣告中包含陣列長度永遠是不合法的!如:int[5] arr; 。因為,宣告的時候並沒有例項化任何物件,只有在例項化陣列物件時,JVM才分配空間,這時才與長度有關。

5、在陣列構造的時候必須指定長度,因為JVM要知道需要在堆上分配多少空間。反例:int[] arr = new int[];

6、多維陣列的宣告。int[][][] arr; 是三維int型陣列。

7、一維陣列的構造。形如:String[] sa = new String[5];

或者分成兩句:String[] sa; sa = new String[5];

8、原始型別陣列元素的預設值。對於原始型別陣列,在用new構造完成而沒有初始化時,JVM自動對其進行初始化。預設值:byte、short、 int、long--0 float--0.0f double--0.0 boolean--false char--'"u0000'。(無論該陣列是成員變數還是區域性變數)

9、物件型別陣列中的引用被預設初始化為null。如:Car[] myCar = new Car[10]; 相當於從myCar[0]到myCar[9]都這樣被自動初始化為myCar[i] = null;

10、物件型別的陣列雖然被預設初始化了,但是並沒有呼叫其建構函式。也就是說:Car[] myCar = new Car[10];只建立了一個myCar陣列物件!並沒有建立Car物件的任何例項!

11、多維陣列的構造。float[][] ratings = new float[9][]; 第一維的長度必須給出,其餘的可以不寫,因為JVM只需要知道賦給變數ratings的物件的長度。

12、陣列索引的範圍。陣列中各個元素的索引是從0開始的,到length-1。每個陣列物件都有一個length屬性,它儲存了該陣列物件的長度。(注意和String物件的length()方法區分開來,這兩者沒有統一起來是很遺憾的。)

13、Java有陣列下標檢查,當訪問超出索引範圍時,將產生ArrayIndexOutOfBoundsException執行時異常。注意,這種下標 檢查不是在編譯時刻進行的,而是在執行時!也就是說int[] arr = new int[10]; arr[100] = 100; 這麼明顯的錯誤可以通過編譯,但在執行時丟擲!

Java的陣列下標檢查是需要額外開銷的,但是出於安全的權衡還是值得的,因為很多語言在使用陣列時是不安全的,可以任意訪問自身記憶體塊外的陣列,編譯執行都不會報錯,產生難以預料的後果!

 

在Java中,陣列是一種效率最高的儲存和隨機訪問物件引用序列的方式。不過
陣列一旦建立,大小就被固定。

    ·只有陣列才能持有基本資料型別,其它各類的容器都沒有這個能力。

    ·陣列也是一個物件,它唯一的成員是length。“[]”語法是訪問陣列物件的唯
一方式。


二、Arrays類

    ·java.util.Arrays類有一套static方法,提供運算元組的實用功能。比如:
equal()用於比較兩個陣列是否相等;fill()用某個值填充陣列;sort()對陣列排序;
binarySearch()在已排序的陣列中查詢元素;asList()將陣列轉為List容器。

    ·複製陣列用System.arraycopy()效率最好,它對物件的複製屬於淺拷貝(只復
制引用)。

    ·陣列的排序涉及到程式設計的基本目標:將保持不變的事物(排序的演算法)與會
發生變化的事物(排序的方式)相分離。使用回撥技術可以達到這個目標。Java有兩種
方法提供比較功能:一是實現java.lang.Comparable介面,使類有“天生”的比較能
力;二是運用策略設計模式,通過定義一個實現了java.util.Comparator介面的類創
建一個策略,來實現比較功能。

    ·Arrays.binarySearch()可對已排序的陣列進行快速查詢,但如果陣列未經排
序則後果不可預料。


Java 2 容器類

    ·Java 2 容器類的類庫主要劃分為兩個概念:一是Collection,一組獨立的元
素(又分為兩種:List,保持元素的特定順序;Set,不能有重複元素);二是Map,一
種成對的鍵值對(key-value)物件。

    ·容器類的缺點:只能儲存Object型的引用,丟失了物件的具體型別資訊,且不
能儲存基本資料型別。

    ·迭代器用來遍歷並選擇序列中的物件,不用考慮序列底層的結構。Java的java
.util.Iterator提供了迭代器的功能,方便遍歷容器中的物件。

    ·在使用容器時,儘量將具體實現的容器類向上轉型,使程式碼只與Collection、
List、Set或Map介面打交道。

 

三、list

 

    ·在Java2容器類庫中,主要實現了兩種List:一是ArrayList,優點是隨機訪問
速度快速;二是LinkedList,優點是插入和刪除快速,並可當作棧或佇列用。兩者中
,一般優先考慮使用ArrayList。

    ·容器類返回的迭代器如果具有修改資料功能,則所有修改都會反映到容器中。
四、Set
    ·Set具有與Collection完全一樣的介面,它不儲存重複元素,不保證維護元素
的順序。Java2容器類庫中主要有三種容器類實現了Set介面:HashSet、TreeSet和
LinkedSet,其中HashSet最常用。

    ·HashSet使用了雜湊函式,專門為快速查詢而設計。存入它的物件必須定義好
equals()和hashCode()。HashSet內部由HashMap來維護資料。

    ·TreeSet採用紅黑樹的資料結構排序元素,存入它的物件必須可排序,要麼這
些物件實現了Comparable介面,要麼在TreeSet的構造器中傳入一個Comparator。TreeSet
其實是SortedSet的唯一實現。TreeSet內部由TreeMap來維護資料。

    ·LinkedHashSet內部使用雜湊以加快查詢速度,同時使用連結串列維護元素的儲存
順序(元素插入的次序),但存入它的物件必須定義好equals()和hashCode()。

 

五、MAP:

   ·HashMap是基於散列表的實現(取代了Hashtable),插入和查詢“鍵值對”的開
銷是固定的。HashMap是最常用的Map。

    ·LinkedHashMap類似於HashMap,但迭代遍歷時,取得的“鍵值對”是其插入次
序或LRU次序。

    ·TreeMap是基於紅黑樹的實現,迭代遍歷時,其鍵或鍵值會被排序(次序由Comparable
或Comparator決定)。

    ·WeakHashMap和IdentityHashMap專為解決特殊問題而設計。

    ·由Map返回的Collection(keySet或values方法)背後的資料依然由Map支援,對
Collection的任何修改都會反映到Map中。

    ·在使用雜湊資料結構的容器中,如HashMap和HashSet,存入其中的元素(或鍵
)必須同時覆蓋Object的equals()和hashCode()方法,否則起不到保證唯一的效果。
因為Object中的這兩個方法都是使用物件的地址,記憶體地址總是不相同的。另外,
hashCode()不一定總能返回唯一的標識碼,但equals()必須能夠嚴格判斷兩個物件是
否相同。


    ·設計hashCode()時應注意的要點:1.對同一個物件產生相同的值;2.不依賴於
具有唯一性的物件資訊(如物件的地址);3.必須具有意義,最好基於內容生成雜湊碼
;4.儘量使產生的雜湊碼分佈均勻。(總的來說,為類編寫正確的hashCode和equals
都很需要技巧)

    ·如果既想持有對某個物件的引用,又希望垃圾回收器能夠釋放它們,那麼應該
使用java.lang.ref包中的Reference相關類。

    ·WeakHashMap是一種節省儲存空間的容器,它允許垃圾回收器自動清理那些沒
有普通引用的“鍵”和“值”。實際上,WeakHashMap自動使用WeakReference包裝了
每一個“鍵”物件。

    ·就像Arrays類一樣,Collections提供了一些方便操作Collection或List的靜
態方法。特別地,它還提供了一系列ummodifiableXXX方法,返回一個“只讀”的Set、
List或Map容器。

    ·Java容器有一種保護機制,能夠防止多個程序同時修改同一個容器的內容。如
果在迭代遍歷某個容器的過程中,同時又修改容器的物件,則會丟擲異常。所以,應
該先對容器做完修改操作後再獲取迭代器。

    ·Arrays.asList()方法返回的List並非java.util.ArrayList型別,不支援add、
remove、clear等修改方法,不過可以使用set方法。

    ·在新程式中,不應再使用過時的Vector、Hashtable和Stack容器。