Java 容器(list, set, map)

java容器類庫的簡化圖:

(虛線框表示接口, 實線框表示普通的類,html

空心箭頭表示特定的類實現了接口, 實心箭頭表示某個類能夠生成箭頭所指的類對象)java

image

 

繼承Collection的主要有Set 和 List.編程

 

List:

ArrayList    內部實現是用數組, 隨機訪問速度快, 刪除或插入元素速度慢。數組

LinkedList  內部實現是用鏈表, 隨機訪問速度慢,刪除和插入元素相對較快。ide

平時最佳的作法多是將ArrayList做爲默認首選,只有你須要使用額外的功能,或者由於常常從表中插入或刪除元素致使程序性能變差的時候,纔去選擇LinkedList。函數

Vector和Stack是過去遺留下來的類,目的只是爲了支持老程序,應該在編寫程序時儘可能避免使用它們。性能

 

Set:

Hashthis

HashSet: 爲快速查找而設計,能夠認爲是基於哈希表的實現。 存入HashSet的元素必須定義hashCode().spa

LinkedHashSet: 具備HashSet的查詢速度且內部使用鏈表維護元素的順序(按插入的順序或最近最少使用順序)線程

 

Tree

TreeSet:保持次序的Set,底層爲樹結構(紅黑樹)。使用它能夠從Set提取有序的序列。元素必須實現Comparable接口或者在構造TreeSet時傳入Comparator參數。

 

 1 class Stone {
 2     private int volume;
 3 
 4     public Stone(int volume) {
 5         this.volume = volume;
 6     }
 7 
 8     public int getVolume() {
 9         return volume;
10     }
11 
12     //...........省略..........//
13 }
14 
15 class Stick implements Comparable{
16     private int length;
17 
18     public Stick(int length) {
19         this.length = length;
20     }
21 
22     public int getLength() {
23         return length;
24     }
25 
26     @Override
27     public int compareTo(Object o) {
28         Stick st = (Stick)o;
29         return this.getLength() - st.getLength();
30     }
31 
32     //...........省略..........//
33 }
34 
35 public class MyComparator implements Comparator<Stone>{
36 
37     @Override
38     public int compare(Stone st1, Stone st2) {
39         return st1.getVolume() - st2.getVolume();
40     }
41 
42     public static void main(String[] args) {
43         new TreeSet<Stone>(new MyComparator()); //傳入Comparator
44 
45         new TreeSet<Stick>(); //Stick實現了Comparable
46     }
47 }
View Code

 

 

不論是散列存儲仍是樹形存儲,元素都必須實現equals()方法雖然只有當時被放入HashSet或LinkedHashSet是hashCode()纔是必須的,可是,對於良好的編程風格,應該在覆蓋equals()方法的同時也覆蓋hashCode()方法。

 

equals()方法必須知足5個條件:

1. 自反性。 對任意x,    x.equals(x)必定爲true

2. 對稱性。 對任意x、y,     若是y.equals(x)爲true, x.equals(y)也爲true

3. 傳遞性。 對任意x、y、z, 若是x.equals(y), y.equals(z)都爲true, x.equals(z)也應該爲true

4. 一致性。 對任意x、y,   若是對象中用於等價比較的信息沒有改變,那麼不管調用x.equals(y)多少次,其返回結果都應該一致。

5. 對於任何不是null的x,     x.equals(null)必定爲false

 

hashCode()的編寫建議(Effective Java):

1. 給result(int型)一個非零的初始值

2. 爲對象內每一個有意義的域f(即每一個能夠作equals()操做的域)計算出一個int散列碼c

域類型

計算

boolean c = ( f ? 0 : 1)

byte, char, short, 或 int

c = (int)f
long c = (int)(f ^ (f>>>32))
float c = Float.floatToIntBits(f);
double

long l = Double.doubleToLongBits(f);
c = (int)(1 ^ (l>>>32))

Object

c = f.hashCode( )
Array 對數組中的每一個元素應用上述規則

 

3. 合併計算獲得的散列碼 result = 37 * result + c

4. 返回 result

5. 檢查hashCode()最後生成的結果,確保相同的對象有相同的散列碼

 

 

SortedSet(接口)保證元素處於排序狀態(按對象的比較函數對元素排序),主要方法有:

Comparator comparator()  返回當前Set使用的Comparator,若是返回空,表示以天然排序(即按元素實現的Comparable中

                                     compareTo()方法排序)。

Object first() 返回容器的第一個元素

Object last() 返回容器的最後一個元素

SortedSet subSet(fromElement, toElement) 生成此Set的子集,範圍從fromElement(包含)到toElement(不包含)

SortedSet headSet(toElement) 生成此Set的子集,由小於toElement的元素組成

SortedSet tailSet(fromElement) 生成此Set的子集,有大於等於fromElement的元素組成

 

TreeSet實現SortedSet,包括SortedSet的方法。

 

 

可選操做

在Collection接口中執行各類添加和移除的方法都是可選的。也就是說實現Collection接口的類並不須要爲這些方法提供有意義的功能實現。這違反了面向對象設計中的規則(不管你選擇如何實現接口,應該保證可以向該接口發送這些消息)。

可選操做聲明調用某些方法將不會執行有意義的行爲,相反,它們會拋出異常。

可選操做是邏輯上的,在實現接口時,仍是須要覆蓋接口所謂的可選方法,只不過你不必定要提供有意義的實現,若是不支持該可選方法,能夠在該方法出拋出UnsupportedOperationException。

 

那麼爲何須要將方法定義爲可選呢?

這樣能夠防止設計中出現接口過多的狀況。

好比如今有下面三種需求(固然能夠有更多不一樣的需求)

不能修改集合內容的容器,

只能添加元素的容器,

只能刪除元素的容器。

那麼如今就須要爲上面三種需求各定義一種接口,顯然這樣比起如今的Collection,須要定義更多的接口。這樣會致使接口過多,使整個容器類庫更加複雜。

注意:UnsupportedOperationException必須是一個罕見的異常。即對大多數類來講,全部操做都應該能夠工做,只有在特列中才會有未得到支持的操做。

 

快速報錯(fail-fast)

java容器有一種保護機制,可以防止多個進程同時修改同一容器的內容。

若是在迭代遍歷某個容器的過程當中,另外一個進程介入其中,而且插入、刪除或修改此容器內的某個對象,那麼就容易出現問題。

java容器類類庫採用fail-fast機制。他會探查容器上除了當前線程所進行的操做以外的全部變化,一旦發現其它進程修改了容器,就會馬上拋出ConcurrentModificationException異常。

示例:

 1 import java.util.*;
 2 public class FailFast {
 3     public static void main(String[] args) {
 4         Collection<String> c = new ArrayList<String>();
 5         Iterator<String> it = c.iterator();
 6         c.add("An object");
 7         try {
 8             String s = it.next();
 9         } catch(ConcurrentModificationException e) {
10             System.out.println(e);
11         }
12     }
13 } 
14 /* Output:
15 java.util.ConcurrentModificationException
16 *///:~
View Code

 

Map

HashMap  基於散列表的實現(它取代了HashTable, HashTable是過期的類)。

LinkedHashMap 相似與HashMap, 可是迭代遍歷時,取得「鍵值對」的順序是其插入的順序

                       或最近最少使用的順序(若是在構造LiskedHashMap傳入參數accessOrder=true)。

                        比HashMap慢一點,可是在迭代訪問時更快,由於它使用鏈表維護內部的次序。

TreeMap 基於紅黑樹的實現。查看key 或 key-value是,它們會被排序(次序由Comparator或Comparable決定)

 

 

博客園(FOREVER_ENJOY):http://www.cnblogs.com/zyx1314/p/5331282.html

本文版權歸做者全部;歡迎轉載!請註明文章做者和原文鏈接

相關文章
相關標籤/搜索