<address id="xpjh9"><listing id="xpjh9"><meter id="xpjh9"></meter></listing></address>

<address id="xpjh9"><address id="xpjh9"><listing id="xpjh9"></listing></address></address>
<noframes id="xpjh9">
<noframes id="xpjh9">

<address id="xpjh9"><address id="xpjh9"><listing id="xpjh9"></listing></address></address>
    <form id="xpjh9"></form><address id="xpjh9"><listing id="xpjh9"><menuitem id="xpjh9"></menuitem></listing></address>

      <noframes id="xpjh9">
      VB.net 2010 視頻教程 VB.net 2010 視頻教程 VB.net 2010 視頻教程
      SQL Server 2008 視頻教程 c#入門經典教程 Visual Basic從門到精通視頻教程
      當前位置:
      首頁 > 編程開發 > Java教程 >
      • java教程之關于 Java Collections API 您不知道的 5 件事

      • 2015-01-24 09:43 來源:未知

      關于 Java Collections API 您不知道的 5 件事,第(相關java教程)1 部分

      對于很多 Java 開發人員來說,Java Collections API 是標準 Java 數組及其所有缺點的一個非常需要的替代品。將 Collections 主要與 ArrayList 聯系到一起本身沒有錯,但是對于那些有探索精神的人來說,這只是 Collections 的冰山一角。

      1、  Collections 比數組好

      剛接觸 Java 技術的開發人員可能不知道,Java 語言最初包括數組,是為了應對上世紀 90 年代初期 C++ 開發人員對于性能方面的批評。從那時到現在,我們已經走過一段很長的路,如今,與 Java Collections 庫相比,數組不再有性能優勢。
      例如,若要將數組的內容轉儲到一個字符串,需要迭代整個數組,然后將內容連接成一個 String;而 Collections 的實現都有一個可用的 toString() 實現。
      除少數情況外,好的做法是盡快將遇到的任何數組轉換成集合。于是問題來了,完成這種轉換的最容易的方式是什么?事實證明,Java Collections API 使這種轉換變得容易,如清單 1 所示:
      清單 1. ArrayToList
      import java.util.*;
       
      public class ArrayToList
      {
          public static void main(String[] args)
          {
              // This gives us nothing good
              System.out.println(args);
              
              // Convert args to a List of String
              List<String> argList = Arrays.asList(args);
              
              // Print them out
              System.out.println(argList);
          }
      }
      注意,返回的 List 是不可修改的,所以如果嘗試向其中添加新元素將拋出一個 UnsupportedOperationException。
      而且,由于 Arrays.asList() 使用 varargs 參數表示添加到 List 的元素,所以還可以使用它輕松地用以 new 新建的對象創建 List。

      2、  迭代的效率較低

      將一個集合(特別是由數組轉化而成的集合)的內容轉移到另一個集合,或者從一個較大對象集合中移除一個較小對象集合,這些事情并不鮮見。
      您也許很想對集合進行迭代,然后添加元素或移除找到的元素,但是不要這樣做。
      在此情況下,迭代有很大的缺點:
      l  每次添加或移除元素后重新調整集合將非常低效。
      l  每次在獲取鎖、執行操作和釋放鎖的過程中,都存在潛在的并發困境。
      l  當添加或移除元素時,存取集合的其他線程會引起競爭條件。
      可以通過使用 addAll 或 removeAll,傳入包含要對其添加或移除元素的集合作為參數,來避免所有這些問題。

      3、  用 for 循環遍歷任何 Iterable

      Java 5 中加入 Java 語言的最大的便利功能之一,增強的 for 循環,消除了使用 Java 集合的最后一道障礙。
      以前,開發人員必須手動獲得一個 Iterator,使用 next() 獲得 Iterator 指向的對象,并通過 hasNext() 檢查是否還有更多可用對象。從 Java 5 開始,我們可以隨意使用 for 循環的變種,它可以在幕后處理上述所有工作。
      實際上,這個增強適用于實現 Iterable 接口的任何對象,而不僅僅是 Collections。
      清單 2 顯示通過 Iterator 提供 Person 對象的孩子列表的一種方法。 這里不是提供內部 List 的一個引用 (這使 Person 外的調用者可以為家庭增加孩子 — 而大多數父母并不希望如此),Person 類型實現 Iterable。這種方法還使得 for 循環可以遍歷所有孩子。
      清單 2. 增強的 for 循環:顯示孩子
      // Person.java
      import java.util.*;
       
      public class Person
          implements Iterable<Person>
      {
          public Person(String fn, String ln, int a, Person... kids)
          {
              this.firstName = fn; this.lastName = ln; this.age = a;
              for (Person child : kids)
                  children.add(child);
          }
          public String getFirstName() { return this.firstName; }
          public String getLastName() { return this.lastName; }
          public int getAge() { return this.age; }
          
          public Iterator<Person> iterator() { return children.iterator(); }
          
          public void setFirstName(String value) { this.firstName = value; }
          public void setLastName(String value) { this.lastName = value; }
          public void setAge(int value) { this.age = value; }
          
          public String toString() { 
              return "[Person: " +
                  "firstName=" + firstName + " " +
                  "lastName=" + lastName + " " +
                  "age=" + age + "]";
          }
          
          private String firstName;
          private String lastName;
          private int age;
          private List<Person> children = new ArrayList<Person>();
      }
       
      // App.java
      public class App
      {
          public static void main(String[] args)
          {
              Person ted = new Person("Ted", "Neward", 39,
                  new Person("Michael", "Neward", 16),
                  new Person("Matthew", "Neward", 10));
       
              // Iterate over the kids
              for (Person kid : ted)
              {
                  System.out.println(kid.getFirstName());
              }
          }
      }
      在域建模的時候,使用 Iterable 有一些明顯的缺陷,因為通過 iterator() 方法只能那么 “隱晦” 地支持一個那樣的對象集合。但是,如果孩子集合比較明顯,Iterable 可以使針對域類型的編程更容易,更直觀。

      4、  經典算法和定制算法

      您是否曾想過以倒序遍歷一個 Collection?對于這種情況,使用經典的 Java Collections 算法非常方便。
      在上面的 清單 2 中,Person 的孩子是按照傳入的順序排列的;但是,現在要以相反的順序列出他們。雖然可以編寫另一個 for 循環,按相反順序將每個對象插入到一個新的 ArrayList 中,但是 3、4 次重復這樣做之后,就會覺得很麻煩。
      在此情況下,清單 3 中的算法就有了用武之地:
      清單 3. ReverseIterator
      public class ReverseIterator
      {
          public static void main(String[] args)
          {
              Person ted = new Person("Ted", "Neward", 39,
                  new Person("Michael", "Neward", 16),
                  new Person("Matthew", "Neward", 10));
       
              // Make a copy of the List
              List<Person> kids = new ArrayList<Person>(ted.getChildren());
              // Reverse it
              Collections.reverse(kids);
              // Display it
              System.out.println(kids);
          }
      }
      Collections 類有很多這樣的 “算法”,它們被實現為靜態方法,以 Collections 作為參數,提供獨立于實現的針對整個集合的行為。
      而且,由于很棒的 API 設計,我們不必完全受限于 Collections 類中提供的算法 — 例如,我喜歡不直接修改(傳入的 Collection 的)內容的方法。所以,可以編寫定制算法是一件很棒的事情,例如清單 4 就是一個這樣的例子:
      清單 4. ReverseIterator 使事情更簡單
      class MyCollections
      {
          public static <T> List<T> reverse(List<T> src)
          {
              List<T> results = new ArrayList<T>(src);
              Collections.reverse(results);
              return results;
          }
      }

      5、  擴展 Collections API

      以上定制算法闡釋了關于 Java Collections API 的一個最終觀點:它總是適合加以擴展和修改,以滿足開發人員的特定目的。
      例如,假設您需要 Person 類中的孩子總是按年齡排序。雖然可以編寫代碼一遍又一遍地對孩子排序(也許是使用 Collections.sort 方法),但是通過一個 Collection 類來自動排序要好得多。
      實際上,您甚至可能不關心是否每次按固定的順序將對象插入到 Collection 中(這正是 List 的基本原理)。您可能只是想讓它們按一定的順序排列。
      java.util 中沒有 Collection 類能滿足這些需求,但是編寫一個這樣的類很簡單。只需創建一個接口,用它描述 Collection 應該提供的抽象行為。對于 SortedCollection,它的作用完全是行為方面的。
      清單 5. SortedCollection
      public interface SortedCollection<E> extends Collection<E>
      {
          public Comparator<E> getComparator();
          public void setComparator(Comparator<E> comp);
      }
      編寫這個新接口的實現簡直不值一提:
      清單 6. ArraySortedCollection
      import java.util.*;
       
      public class ArraySortedCollection<E>
          implements SortedCollection<E>, Iterable<E>
      {
          private Comparator<E> comparator;
          private ArrayList<E> list;
              
          public ArraySortedCollection(Comparator<E> c)
          {
              this.list = new ArrayList<E>();
              this.comparator = c;
          }
          public ArraySortedCollection(Collection<? extends E> src, Comparator<E> c)
          {
              this.list = new ArrayList<E>(src);
              this.comparator = c;
              sortThis();
          }
       
          public Comparator<E> getComparator() { return comparator; }
          public void setComparator(Comparator<E> cmp) { comparator = cmp; sortThis(); }
          
          public boolean add(E e)
          { boolean r = list.add(e); sortThis(); return r; }
          public boolean addAll(Collection<? extends E> ec) 
          { boolean r = list.addAll(ec); sortThis(); return r; }
          public boolean remove(Object o)
          { boolean r = list.remove(o); sortThis(); return r; }
          public boolean removeAll(Collection<?> c)
          { boolean r = list.removeAll(c); sortThis(); return r; }
          public boolean retainAll(Collection<?> ec)
          { boolean r = list.retainAll(ec); sortThis(); return r; }
          
          public void clear() { list.clear(); }
          public boolean contains(Object o) { return list.contains(o); }
          public boolean containsAll(Collection <?> c) { return list.containsAll(c); }
          public boolean isEmpty() { return list.isEmpty(); }
          public Iterator<E> iterator() { return list.iterator(); }
          public int size() { return list.size(); }
          public Object[] toArray() { return list.toArray(); }
          public <T> T[] toArray(T[] a) { return list.toArray(a); }
          
          public boolean equals(Object o)
          {
              if (o == this)
                  return true;
              
              if (o instanceof ArraySortedCollection)
              {
                  ArraySortedCollection<E> rhs = (ArraySortedCollection<E>)o;
                  return this.list.equals(rhs.list);
              }
              
              return false;
          }
          public int hashCode()
          {
              return list.hashCode();
          }
          public String toString()
          {
              return list.toString();
          }
          
          private void sortThis()
          {
              Collections.sort(list, comparator);
          }
      }
      這個實現非常簡陋,編寫時并沒有考慮優化,顯然還需要進行重構。但關鍵是 Java Collections API 從來無意將與集合相關的任何東西定死。它總是需要擴展,同時也鼓勵擴展。
      當然,有些擴展比較復雜,例如 java.util.concurrent 中引入的擴展。但是另一些則非常簡單,只需編寫一個定制算法,或者已有 Collection 類的簡單的擴展。
      擴展 Java Collections API 看上去很難,但是一旦開始著手,您會發現遠不如想象的那樣難。
      相關教程
      江苏快3 溧阳 | 陇南 | 衡阳 | 宜都 | 博尔塔拉 | 灌南 | 滕州 | 温州 | 郴州 | 苍南 | 舟山 | 和田 | 东方 | 郴州 | 湘西 | 赣州 | 芜湖 | 温岭 | 滨州 | 襄阳 | 博罗 | 滁州 | 汝州 | 安阳 | 清徐 | 任丘 | 汉川 | 晋中 | 邵阳 | 定州 | 鄂尔多斯 | 徐州 | 德清 | 来宾 | 吉林 | 运城 | 沧州 | 朔州 | 溧阳 | 乐清 | 吐鲁番 | 潍坊 | 东海 | 淮北 | 衡水 | 义乌 | 岳阳 | 顺德 | 牡丹江 | 吕梁 | 公主岭 | 海拉尔 | 湖州 | 四平 | 北海 | 滁州 | 台山 | 通化 | 宝应县 | 昌吉 | 济宁 | 邵阳 | 昆山 | 梧州 | 张北 | 大庆 | 榆林 | 五家渠 | 湘西 | 香港香港 | 内蒙古呼和浩特 | 宁德 | 昭通 | 沧州 | 枣庄 | 吐鲁番 | 和县 | 黄石 | 丽水 | 昭通 | 黑龙江哈尔滨 | 邹平 | 新余 | 塔城 | 云浮 | 莱芜 | 牡丹江 | 塔城 | 铜川 | 柳州 | 上饶 | 枣庄 | 林芝 | 固原 | 东方 | 肥城 | 福建福州 | 凉山 | 宁夏银川 | 甘南 | 山南 | 中卫 | 内江 | 德州 | 金华 | 萍乡 | 台中 | 阿坝 | 大丰 | 白沙 | 海门 | 潮州 | 漯河 |