walterwing  
          日歷
          <2008年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789
          統計
          • 隨筆 - 12
          • 文章 - 1
          • 評論 - 7
          • 引用 - 0

          導航

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

           
          3. List

          List是一種有順序的Collection,并允許有重復的元素。除了從Colleciton接口繼承過來的方法之外,List還額外增加了如下一些操作:
          • Positional access — manipulates elements based on their numerical position in the list
          • Search — searches for a specified object in the list and returns its numerical position
          • Iteration — extends Iterator semantics to take advantage of the list's sequential nature
          • Range-view — performs arbitrary range operations on the list.
          List接口定義如下:

          public interface List<E> extends Collection<E> {
              
          // Positional access
              E get(int index);
              E set(
          int index, E element);    //optional
              boolean add(E element);         //optional
              void add(int index, E element); //optional
              E remove(int index);            //optional
              boolean addAll(int index,
                  Collection
          <? extends E> c); //optional

              
          // Search
              int indexOf(Object o);
              
          int lastIndexOf(Object o);

              
          // Iteration
              ListIterator<E> listIterator();
              ListIterator
          <E> listIterator(int index);

              
          // Range-view
              List<E> subList(int from, int to);
          }

          Java platform提供了兩種general-purpose的List實現類:

          ·ArrayList:性能最好,相當于可變長度的數組

          ·LinkedList:適合于插入刪除操作。


          關于從Collection繼承過來的操作,有幾點需要注意:

          ·boolean remove(Object element); 是刪除在List中第一個出現的element(因為List允許重復元素)

          ·add和addAll操作,是把元素加入到當前List的隊尾

          和Set一樣的是,List也增強了對equals和hashCode操作的約束,任意兩個List的實現類,都可以進行比較,只要他們包含的元素相同,那么equals就返回true


          由于List是有順序的,我們可以根據元素的位置來進行操作。比如下面的例子演示了如何交換兩個不同位置的元素:

          public static <E> void swap(List<E> a, int i, int j) {
              E tmp 
          = a.get(i);
              a.set(i, a.get(j));
              a.set(j, tmp);
          }

          有了這個函數,我們就可以很容易的得到Collections類中的shuffle方法:

          public static void shuffle(List<?> list, Random rnd) {
              
          for (int i = list.size(); i > 1; i--)
                  swap(list, i 
          - 1, rnd.nextInt(i));
          }

          既然提到了shuufle,那么來看一下他的一個簡單應用:將傳進來的參數打亂順序

          public class Shuffle {
              
          public static void main(String[] args) {
                  List
          <String> list = new ArrayList<String>();
                  
          for (String a : args)
                      list.add(a);
                  Colle?ions.shuffle(list, 
          new Random());
                  System.out.println(list);
              }
          }

          而實際上,我們可以用更簡潔的代碼來完成上面的功能,那就是利用Array的asList方法。

          我們前面提到過,List可以看作是可變長度的Array,反過來,我們也可以把Array看成是一種特殊的list。因此,java platform就提供了將ArrayC?%8?換成List的方法asList。但要注意的是,asList方法返回的是一個List,而不是任何一種general-purpose的實現類。因為他返回的這個list并不實現add、remove方法-只能看,不能動。

          public class Shuffle {
              
          public static void main(String[] args) {
                  List
          <String> list = Arrays.asList(args);
                  Collections.shuffle(list);
                  System.out.println(list);
              }
          }


          List不光實現了Iterator,他還根據自己有序的特性,實現了一種特殊的Iterator-ListIterator:

          public interface ListIterator<E> extends Iterator<E> {
              
          boolean hasNext();
              E next();
              
          boolean hasPrevious();
              E previous();
              
          int nextIndex();
              
          int previousIndex();
              
          void remove(); //optional
              void set(E e); //optional
              void add(E e); //optional
          }

          我們看到,ListIterator能自由的控制遍歷的方向,而且能隨時得到當前所處的位置,另外,也能在遍歷期間進行各種修改操作(add、set、remove)。
          還有一點:Iterator只能刪除,不能修改(add、set),而ListIterator可以
          為了對比,我還是把原本的Iterator貼出來:

          public interface Iterator<E> {
              
          boolean hasNext();
              E next();
              
          void remove(); //optional
          }

          ListIterator不僅僅是擴展了這些方法,連構造方法都多了一個:

          除了普通的ListIterator<E> listIterator(); 外,還可以用ListIterator<E> listIterator(int index);來獲得指定位置處的listIterator。這樣我們就可以從任意位置,朝任意方向開始遍歷了。


          下面關于List中的subList方法,有一點需要注意,那就是subList返回的是一個引用,而不是新創建的List。這就意味這你對subList做的任何操作,都將影響到原來的list(我們稱其為backlist)。因此,subList只能用于臨時的對backlist的局部操作,而且要盡早結束,避免由于其他地方對backlist的修改導致subList出現問題。當然,有一種這種的辦法,就是你根據返回的subList,創建一個新的list。

          在Collections類中定義了很多算法,適用于List:
          • sort — sorts a List using a merge sort algorithm, which provides a fast, stable sort. (A stable sort is one that does not reorder equal elements.)
          • shuffle — randomly permutes the elements in a List.
          • reverse — reverses the order of the elements in a List.
          • rotate — rotates all the elements in a List by a specified distance.
          • swap — swaps the elements at specified positions in a List.
          • replaceAll — replaces all occurrences of one specified value with another.
          • fill — overwrites every element in a List with the specified value.
          • copy — copies the source List into the destination List.
          • binarySearch — searches for an element in an ordered List using the binary search algorithm.
          • indexOfSubList — returns the index of the first sublist of one List that is equal to another.
          • lastIndexOfSubList — returns the index of the last sublist of one List that is equal to another.
          具體內容將在介紹算法時再繼續深入


          4. Queue

          Queue就是數據結構中介紹的隊列。除了Collection中提供的基本操作外,他還額外提供了一些關于插入、刪除、檢查的操作。

          Queue的定義如下:

          public interface Queue<E> extends Collection<E> {
              E element();
              
          boolean offer(E e);
              E peek();
              E poll();
              E remove();
          }

          Queue有一個特點,就是它所提供的方法都有兩種形態:

          ·失敗時拋異常的
          ·失敗時返回特殊值的(null或者false)

          Queue Interface Structure
            Throws exception Returns special value
          Insert add(e) offer(e)
          Remove remove() poll()
          Examine element() peek()

          前面提到過,Queue是有順序的Collection,而且一般的Queue都遵?%???FIFO,就像數據結構里介紹的那樣。但也有例外,比如priority queue,可以定義自己的排序方式。但不管順序是怎樣的,排在頭部的都是將要被remove()或者poll()方法拿出來的那個元素。而當插入的時候,FIFO的queue當然是插入隊尾,但其他形式的queue則由自身的排序規則決定插入位置

          有些queue是由長度限制的,被稱為“bounded queue”,像在java.util.concurrent中實現的一些queue就是bounded,但java.uti8B?%8?的所有queue都是沒有長度限制的。

          ·add(e)方法當超過queue的長度限制的時候,就將拋出IllegalStateException;而offer(e)方法是被設計專門用在bounded queue上的,當超過隊列限制時,該方法將返回false

          ·當隊列為空時,調用remove()方法將拋
          NoSuchElementException;poll()方法將返回null

          ·element()和peek()方法和remove()、poll()基本是一樣的,唯一的區別是他們只是取得頭部元素的值,而并不刪除

          需要注意的一點是:
          Queue 實現通常不允許插入 null 元素,盡管某些實現(如 LinkedList)并不禁止插入 null。即使在允許 null 的實現中,也不應該將 null 插入到 Queue 中,因為 null 也用作 poll 方法的一個特殊返回值,表明隊列不包含元素。

          與Set和List不同的是,Queue 實現通常未定義 equalshashCode 方法的基于元素的版本,而是從 Object 類繼承了基于身份的版本,因為對于具有相同元素但有不同排序屬性的隊列而言,基于元素的相等性并非總是定義良好的。

          另外,Queue 接口并未定義阻塞隊列的方法,而這在并發編程中是很常見的。java.util.cuncurrent.BlockingQueue 接口定義了那些等待元素出現或等待隊列中有可用空間的方法,這些方法擴展了此接口。


          5. Map

          Map存儲的是“鍵-值”對,他不允許key重復,每個key最多指向一個value。

          下面是Map的定義:

          public interface Map<K,V> {

              
          // Basic operations
              V put(K key, V value);
              V get(Object key);
              V remove(Object key);
              
          boolean containsKey(Object key);
              
          boolean containsValue(Object value);
              
          int size();
              
          boolean isEmpty();

              
          // Bulk operations
              void putAll(Map<? extends K, ? extends V> m);
              
          void clear();

              
          // Collection Views
              public Set<K> keySet();
              
          public Collection<V> values();
              
          public Set<Map.Entry<K,V>> entrySet();

              
          // Interface for entrySet elements
              public interface Entry {
                  K getKey();
                  V getValue();
                  V setValue(V value);
              }
          }

          Java platform提供了三種general purpose的Map實現類:HashMap、TreeMap、LinkedHashMap,他們很類似于Set中的HashSet、TreeSet、LinkedHashSet。如果你忘了這三者的區別,那就看下面一個簡單的例子:

          public class Freq {
              
          public static void main(String[] args) {
                  Map
          <String, Integer> m = new HashMap<String, Integer>();

                  
          // Initialize frequency table from command line
                  for (String a : args) {
                      Integer freq 
          = m.get(a);
                      m.put(a, (freq 
          == null? 1 : freq + 1);
                  }

                  System.out.println(m.size() 
          + " distinct words:");
                  System.out.println(m);
              }
          }

          運行:

          java Freq if it is to be it is up to me to delegate

          返回的結果是:

          8 distinct words:
          {to
          =3, delegate=1, be=1, it=2, up=1if=1, me=1, is=2}

          如果我們將HashMap換成TreeMap,那么將按字母順序輸出:

          8 distinct words:
          {be
          =1, delegate=1if=1, is=2, it=2, me=1, to=3, up=1}

          如果換成LinkedHashMap,那么將按插入順序輸出:

          8 distinct words:
          {
          if=1, it=2, is=2, to=3, be=1, up=1, me=1, delegate=1}


          和Collecton一樣,所有通用的Map實現類應該提供兩個“標準的”構造方法:一個 void(無參數)構造方法,用于創建空映射;一個是帶有單個 Map 類型參數的構造方法,用于創建一個與其參數具有相同鍵-值映射關系的新映射。實際上,后一個構造方法允許用戶復制任意映射,生成所需類的一個等價映射。盡管無法強制執行此建議(因為接口不能包含構造方法),但是 JDK 中所有通用的Map實現都遵從它。

          和Set、List一樣,Map增強了equals和hashCode方法的約束,任意兩個Map的實現類的對象都可以進行比較,只要二者所包含的鍵值對完全相同,那二者就是相等的。


          Map 接口提供三種collection 視圖,允許以鍵集、值集或鍵-值映射關系集的形式查看某個映射的內容。映射順序 定義為迭代器在映射的 collection 視圖上返回其元素的順序。某些映射實現可明確保證其順序,如 TreeMap 類;另一些映射實現則不保證順序,如 HashMap 類。
          • keySet — the Set of keys contained in the Map.
          • values — The Collection of values contained in the Map. This Collection is not a Set, because multiple keys can map to the same value.
          • entrySet — the Set of key-value pairs contained in the Map. The Map interface provides a small nested interface called Map.Entry, the type of the elements in this Set.
          這三種視圖是用來遍歷Map的唯一途徑。

          posted on 2008-07-03 16:13 This is Wing 閱讀(361) 評論(0)  編輯  收藏 所屬分類: Java基礎
           
          Copyright © This is Wing Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 格尔木市| 云浮市| 湟源县| 延寿县| 兴安盟| 云安县| 贵南县| 彝良县| 项城市| 深水埗区| 偏关县| 西乡县| 舟曲县| 洛阳市| 卢湾区| 鹤岗市| 石林| 始兴县| 岳西县| 富裕县| 神木县| 龙岩市| 宽甸| 鄄城县| 昭觉县| 乌兰浩特市| 鱼台县| 平山县| 华安县| 巫溪县| 亚东县| 前郭尔| 彩票| 麻阳| 石景山区| 伊宁县| 潼关县| 桃源县| 三亚市| 大田县| 兰溪市|