馴服 Tiger: 集合框架

發表于:2007-05-24來源:作者:點擊數: 標簽:框架Tiger集合可能已經
您可能已經非常熟悉新的 Java 5 語言的泛型支持、并發工具庫以及它們對集合框架的影響,但是這些并不是 Tiger 中集合框架的惟一變化。這個月,John Zukowski 將介紹另外幾項增強,其中包括新的集合類型,以及現有類和接口的附加特性。請參與本文的 討論論壇
您可能已經非常熟悉新的 Java™ 5 語言的泛型支持、并發工具庫以及它們對集合框架的影響,但是這些并不是 Tiger 中集合框架的惟一變化。這個月,John Zukowski 將介紹另外幾項增強,其中包括新的集合類型,以及現有類和接口的附加特性。請參與本文的 討論論壇。(可以單擊文章頂部的 討論 來訪問該論壇。)

JDK 5.0 中最吸引人的地方在于集合框架的一些最突出的特性上,例如:支持泛型的語言級別上的新變化,以及可以在 java.util.concurrent 包中找到的并發集合工具包。實際上,以前在 developerWorks 上的“馴服 Tiger: 并發集合”和“介紹 JDK 5.0 中的泛型”這兩篇教程中介紹了上述特性。但是其他增強還沒有得到足夠的重視。在本文中,我將研究其他三個變化:更新過的 ArraysCollections 類、新的 Queue 接口以及它的 PriorityQueue 實現。

數組(Array)

Arrays 類提供了一系列處理數組的靜態工具方法,這些索引的數據結構的大小是固定的。在 5.0 版本之前,Arrays 類擁有針對原始數據庫類型和通用 Object 類型的每種不同數組類型的 binarySearch()、equals()、fill()sort() 方法。用于將 Object 數組轉換成 List 的附加 asList() 方法仍然有用。Tiger 為所有數組添加了 hashCode()toString() 方法,還添加了特定于 Object 數組的 deepEquals()、deepHashCode()deepToString() 方法??傆嬘?21 個新方法可用:

  • public static boolean deepEquals(Object[] a1, Object[] a2)
  • public static int deepHashCode(Object[] a)
  • public static String deepToString(Object[] a)
  • public static int hashCode(boolean[] a)
  • public static int hashCode(byte[] a)
  • public static int hashCode(char[] a)
  • public static int hashCode(double[] a)
  • public static int hashCode(float[] a)
  • public static int hashCode(int[] a)
  • public static int hashCode(long[] a)
  • public static int hashCode(Object[] a)
  • public static int hashCode(short[] a)
  • public static String toString(boolean[] a)
  • public static String toString(byte[] a)
  • public static String toString(char[] a)
  • public static String toString(double[] a)
  • public static String toString(float[] a)
  • public static String toString(int[] a)
  • public static String toString(long[] a)
  • public static String toString(Object[] a)
  • public static String toString(short[] a)

自從集合框架初次出現在 J2SE 1.2 中以來,人們第一次對實用工具類進行了更改。我無法確定為什么 Sun 要等這么久才進行更改,但是對于可用的幫助器方法系列來說,這些更改是受歡迎的添加。

新添加的第一個方法是 hashCode()。對于任意數組類型,都可以調用 Arrays.hashCode(arrayVar) 方法來獲得格式良好的哈希碼。這個哈希碼可以用作 HashMap 或者其他相關目的的鍵。如果您不知道如何生成良好的哈希碼,那么最好使用 Arrays 類,它能產生更少沖突。Arrays 類生成等價于擁有相同元素的 List 的代碼。

在創建自己的類時,既需要提供 equals() 方法,又需要提供 hashCode() 方法。在 Arrays 的新方法 hashCode() 的幫助下,可以為任何本地數組類型生成哈希碼,而不用在每次需要它的時候折騰您自己。

所有數組類型都可用的另一個方法是 toString()。對于任何數組類型,都可以調用 Arrays.toString(arrayVar) 獲得逗號分隔的元素列表,列表用方括號包圍,如清單 1 的程序所示:


清單 1. 用 Arrays.toString 生成字符串

            import java.util.Arrays;
            public class ArgsToString {
            public static void main(String args[]) {
            System.out.println(Arrays.toString(args));
            }
            }
            

清單 2 顯示了結果:


清單 2. 清單 1 的結果
>java ArgsToString One Two Three
            [One, Two, Three]
            

新的 deepEquals()、deepHashCode()deepToString() 方法的工作方式類似于它們那些非深度(non-deep)的同類,但它們不僅會停下手來處理頂級數組的每個元素,還會更深入地研究生成結果的多維數組。

雖然不是一個新方法,但 asList() 方法在 5.0 的工作方式有所不同。以前,這個方法接受 Object[] 數組作為它的參數?,F在,因為 Tiger 的可變參數列表特性,任何用逗號分隔的列表都可以接受,如清單 3 所示:


清單 3. Arrays.asList 的區別

            import java.util.Arrays;
            public class AsList {
            public static void main(String args[]) {
            // Before
            List before = Arrays.asList(args);
            // After
            List after = Arrays.asList("One", "Two", "Three");
            }
            }
            

如果傳遞給命令行的元素不同,清單 3 中的兩個示例沒必要產生同樣的結果 ,但是它確實展示了 Tiger 在語言級別上的變化如何擴展了 Arrays 原有的 asList() 方法。





集合

Arrays 用于處理不同集合的輔助類是 Collections 類。同樣,這個類也不是一個新類,但是該類的特性已經針對 5.0 作了擴展?,F在有 13 個新方法:

  • checkedCollection()
  • checkedSet()
  • checkedSortedSet()
  • checkedList()
  • checkedMap()
  • checkedSortedMap()
  • emptySet()
  • emptyList()
  • emptyMap()
  • reverseOrder()
  • frequency()
  • disjoint()
  • addAll()

其中 6 個 checked*() 方法工作起來與 6 個 synchronized*()unmodifiable*() 方法類似。使用 synchronized*() 方法時,要向該方法提供一個集合,然后該方法將返回同一個集合的同步的、線程安全的版本。使用 unmodifiable*() 方法時,得到的是指定集合的只讀視圖。除了集合參數之外,checked*() 操作可能還要求第二個或者第三個參數(如清單 4 所示),并返回該集合的動態的類型安全視圖:


清單 4. 檢測后的集合

              public static <E> Collection<E> checkedCollection(
            Collection<E> c, Class<E> type)
            public static <E> Set<E> checkedSet(
            Set<E> s, Class<E> type)
            public static <E> SortedSet<E> checkedSortedSet(
            SortedSet<E> s, Class<E> type)
            public static <E> List<E> checkedList(
            List<E> list, Class<E> type)
            public static <K,V> Map<K,V> checkedMap(
            Map<K,V> m, Class<K> keyType, Class<V> valueType)
            public static <K,V> SortedMap<K,V> checkedSortedMap(
            SortedMap<K,V> m, Class<K> keyType, Class<V> valueType)
            

使用 Java 5.0 平臺,您可能以為:由于將集合聲明為通用集合 (Collection<String> c = new HashSet<String>();),所以不需要進行運行時檢測了。但是如果向工具方法傳遞 String 版本的 HashSet,而工具方法只能處理非通用的 Set,那么該方法可能就會錯誤地向集合添加一個非 String 元素。通過臨時修改程序,用 Collection<String> c = Collections.checkedCollection(new HashSet<String>(), String.class); 添加運行時檢查,您可以迅速發現問題的根源。

三個 empty*() 方法 —— emptySet()、emptyList()emptyMap() —— 生成空的不可改變的集合。雖然也可以用 new ArraySet() 這樣的方法創建空集合,但是還要通過某個 unmodifiable*() 方法才能確保新集合是不可改變的。empty 方法用更理想的方式提供了空的只讀集合。





隊列(Queue)接口

5.0 集合框架較大的一個改變就是添加了新的基接口 Queue。雖然這個接口是在“并發集合”技巧 (請參閱 參考資料)中描述的,但它的應用并不限于并發。在計算機科學中,隊列數據結構是基本的先進先出(FIFO) 結構。項目添加到尾部,并且要從頂部刪除。不僅能添加和刪除元素,還能查看隊列中有哪些元素。清單 5 顯示了 Queue 接口的 5 個方法:


清單 5. Queue 接口

              public boolean offer(Object element)
            public Object remove()
            public Object poll()
            public Object element()
            public Object peek()
            

請記住,Queue 是從 Collection 接口擴展的,所以實現 Queue 接口也就實現了 Collection。在使用 Queue 的實現時,應當將自己限制在接口的方法上。例如,向 Queue 添加元素可以用 Collectionadd() 方法來實現,它在失敗時會拋出未檢測異常。相反,如果大小有限的隊列滿了,那么 offer() 方法會返回 false,而不需要處理隊列滿的異常。

java.util.concurrent 包中具有 Queue 接口的多個實現,但并不包含所有實現。LinkedList 類針對 JDK 5.0 的 Queue 接口作了修正,而 PriorityQueue 是隨 JDK 5.0 添加進來的。余下的實現 —— ArrayBlockingQueue、ConcurrentLinkedQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueueSynchronousQueue —— 都是 java.util.concurrent 包的組成部分。

因為 LinkedList 不是新事物,所以我們來看一下新的 PriorityQueue 類。如清單 6 所示,可以用 6 種方法創建它。在不能使用 Comparator 時,可以使用元素的自然順序來確定優先級。如果元素沒有實現 Comparable 接口,那么就會產生運行時錯誤:


清單 6. PriorityQueue 構造函數

              PriorityQueue()
            PriorityQueue(Collection<? extends E> c)
            PriorityQueue(int initialCapacity)
            PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
            PriorityQueue(PriorityQueue<? extends E> c)
            PriorityQueue(SortedSet<? extends E> c)
            

為了演示 PriorityQueue 的用法,清單 7 中的程序添加了所有命令行元素,并按字母順序處理它們。由于隊列結構是 LinkedList,所以順序應當是典型的 FIFO 順序,但是 PriorityQueue 將根據優先級對元素進行排序:


清單 7. PriorityQueue 的用法

            import java.util.*;
            import java.util.concurrent.*;
            public class Priority {
            public static void main(String args[]) {
            Queue<String> queue =
            new PriorityQueue<String>(Arrays.asList(args));
            String element;
            while ((element = queue.poll()) != null) {
            System.out.println(element);
            }
            }
            }
            

清單 8 顯示了用命令行 one two three four 運行程序之后的輸出 :


清單 8. 清單 7 的結果
>java Priority one two three four
            four
            one
            three
            two
            

關于新的 Queue 接口,有件事需要提一下,這件事與 Collections 類有關:方法 checkedQueue()、emptyQueue()、synchronizedQueue()unmodifiableQueue() 全都是 Collections 類中所缺少的。根據 bug 報告,除了 checkedQueue() 之外,所有類都是故意缺失的。對于 synchronizedQueue(),并發集合是比純粹的包裝器更好的選擇。其他方法則被認為不是必需的。也許 Tiger/6.0 版本中會添加 checkedQueue()(和 checkedBlockingQueue()) 。

原文轉自:http://www.anti-gravitydesign.com

評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97