隨筆-42  評論-42  文章-0  trackbacks-0
          一 我所知道的集合 

            我知道的第一個集合:ArrayList,加入元素非常方便,add(Object elem)。其它的, TreeSet(有序并防止重復), HashMap(名值對), LinkedList(為經常插入或刪除中間元素所設計的高效集合), HashSet(防止重復,可快速找尋符合的元素), LinkedHashMap(類型于HashMap, 但可以記住元素插入的順序,也可以設定成依照元素上次存取的先后來排序)。總的來說,這些集合可以用“順序”和“重復”來區分。

            下面兩圖用來說明3個主要的接口:List, Set 和 Map.(部分)



          二 順序

            順序問題,可以用TreeSet或Collections.sort()來實現。當插入新元素時,TreeSet會花時間找到適當的位置,所以相對要慢了。而ArrayList只要把新加的元素放到最后就好。(當然,ArrayList也有重載的add(index, element )可以插到指定位置,也慢,通常不這樣做。)
            sort(List<T> list) 方法 /* public static <T extends Comparable<? super T>> void sort(List<T> list) */ :只傳入Comparable 接口的 list 作為參數。Comparable有一個方法要實現:compareTo(T o)方法。
            或者用重載的sort()方法:sort(List<T> list, Comparator< ? super T> c)方法 。這樣,就用不著compareTo()方法了。而是要實現Comparator接口,實現compare()方法。
           
          實例1-關于 sort(List<T> list)

          /* Class StudyComparable */
          package conllection;

          import java.util.Collections;
          import java.util.LinkedList;

          public class StudyComparable {
              LinkedList
          <Person> psn = new LinkedList<Person>();

              
          public static void main(String[] args) {
                  StudyComparable sc 
          = new StudyComparable();
                  sc.go();
              }


              
          private void go() {
                  psn.add(
          new Person("one"3));
                  psn.add(
          new Person("two"2));
                  psn.add(
          new Person("three"5));
                  psn.add(
          new Person("five"6));
                  psn.add(
          new Person("eight"8));
                  System.out.println(psn);
                  Collections.sort(psn);
                  System.out.println(psn);
              }

          }



          /* Class Person */

          package conllection;

          public class Person implements Comparable<Person> {
              String name;
              
          int age;

              
          public Person(String n, int a) {
                  name 
          = n;
                  age 
          = a;
              }


              @Override
              
          public int compareTo(Person o) {
                  
          return name.compareTo(o.name);
              }


              @Override
              
          public String toString() {
                  
          return name + "/" + age;
              }

          }


          運行結果:
            [one/3, two/2, three/5, five/6, eight/8]
                  [eight/8, five/6, one/3, three/5, two/2]

            現在,可以按照name來排序了,不過我想用age 來排序,就要改代碼,用Person類中的compareTo()方法進入age的比較。這樣做很不好,所以可以用重載的sort(List<T> list, Comparator<? super T> c)方法。

          實例2-關于 sort(List <T> list, Comparator <? super T> c)

          Class StudyComparator
          package conllection;

          import java.util.ArrayList;
          import java.util.Collections;
          import java.util.Comparator;

          public class StudyComparator {
              ArrayList
          <Person> psn = new ArrayList<Person>();

              
          public static void main(String[] args) {
                  StudyComparator sc 
          = new StudyComparator();
                  sc.go();
              }


              
          class NameComparator implements Comparator<Person> {

                  @Override
                  
          public int compare(Person o1, Person o2) {
                      
          return o1.name.compareTo(o2.name);
                  }


              }


              
          class AgeComparator implements Comparator<Person> {

                  @Override
                  
          public int compare(Person o1, Person o2) {
                      
          return o1.age - o2.age;
                  }


              }


              
          private void go() {
                  psn.add(
          new Person("one"3));
                  psn.add(
          new Person("two"2));
                  psn.add(
          new Person("three"5));
                  psn.add(
          new Person("five"6));
                  psn.add(
          new Person("eight"8));
                  System.out.println(psn);

                  NameComparator nc 
          = new NameComparator();
                  Collections.sort(psn, nc);
                  System.out.println(
          "onName:" + psn);
                  AgeComparator ac 
          = new AgeComparator();
                  Collections.sort(psn, ac);
                  System.out.println(
          "onAge:" + psn);
              }

          }


            Class Person:同例1中的Person.Class 。因為在StudyComparator里面定義了Comparator的實現類,所以Person類不用動,也就是說,在沒有原代碼的情況下也實現了sort,而且可按不同的屬性來進行排序,我更喜歡這個重載的sort()方法。

          運行結果:

          [one/3, two/2, three/5, five/6, eight/8]
          onName:[eight/8, five/6, one/3, three/5, two/2]
          onAge:[two/2, one/3, three/5, five/6, eight/8]


          三 重復

            1 相等 ==

            防止重復,用Set。要解決的第一個問題:兩個對象的引用怎樣才算是重復?答案就是它們是相等的。那么怎樣算‘相等’?顯然不是單純的值相等。‘相等’包括引用相等和對象相等。
            引用相等:引用堆上的同一對象的兩個引用是相等的。如果對兩個引用調用hashCode() ,會得到相同的結果。hashCode()(默認的行為)會返回對象在堆上的特有的唯一序號。顯然,不同對象的引用的hashCode()的值是不同的。
            對象相等:堆上的兩個不同對象,在意義上相同。
            因此,想要兩個不同的對象‘相等’,就必須要override hashCode()和equals()方法

            
          a.equals(b) 的默認行為是執行‘==’,包括了hashCode()的對比。如果equals()方法不被override, 那么兩個對象永遠都不會視為相同。

            2 HashSet 檢查重復:hashCode() 與 equals()

            當把對象放入HashSet時,它會先用對象的hashCode()與已有元素的hashCode()來比較,(如果沒有override過hashCode()方法,那么HashSet 會認為對象間不重復,我們當然要override來確保對象有相同的值)。如果hashCode()相同,再調用其中一個的equals()來檢查對象是否真的相同。如果又相同了,那么加入的操作就不會發生。

            說明:有相同hashCode()的對象也不一定是相等的,感覺有點怪,但的確如此。因為hashCode()用的是雜湊算法,也許剛好使多個對象有了相同的雜湊值。越爛的雜湊算法越容易碰撞。這個屬于數據結構方面的問題了。具體的要問專家了。
          posted on 2008-07-09 02:47 BlueSunshine 閱讀(1217) 評論(3)  編輯  收藏 所屬分類: 學習心得

          評論:
          # re: 學習集合與泛型 2008-07-10 12:07 | BlueSunshine
          四 使用TreeSet

            防止重復又保持有序,可以用TreeSet。

          例3-關于TreeSet 的例子,通過實現Comparator來達到排序。

          package collection;
           
          2 
           
          3 import java.util.Comparator;
           
          4 import java.util.TreeSet;
           
          5 
           
          6 public class TestTree {
           
          7     public static void main(String[] args) {
           
          8         new TestTree().go();
           
          9     }
          10 
          11     private void go() {
          12         Book b1 = new Book("How Cats Work");
          13         Book b2 = new Book("Remix you body");
          14         Book b3 = new Book("Finding Emo");
          15 
          16         SetComparator sc = new SetComparator();
          17         TreeSet<Book> tree = new TreeSet<Book>(sc);
          18 
          19         tree.add(b1);
          20         tree.add(b2);
          21         tree.add(b3);
          22         tree.add(b3);
          23         System.out.println(tree);
          24     }
          25 
          26     class SetComparator implements Comparator<Book> {
          27
           
          28
                   @Override
          29         public int
           compare(Book o1, Book o2) {
          30             return
           o1.title.compareTo(o2.title);
          31
                   }
          32
           
          33     }
          34 }
          35 
          36 
          37 package collection;
          38 
          39 public class Book {
          40     String title;
          41 
          42     public Book(String t) {
          43         title = t;
          44     }
          45 
          46 
          47     @Override
          48     public String toString() {
          49         return title;
          50     }
          51     
          52 }
          53 

            
          例4-關于TreeSet的第2個例子,通過實現Comparable來達到排序

           1 package collection;
           2 
           3 import java.util.TreeSet;
           4 
           5 public class TestTree {
           6     public static void main(String[] args) {
           7         new TestTree().go();
           8     }
           9 
          10     private void go() {
          11         Book b1 = new Book("How Cats Work");
          12         Book b2 = new Book("Remix you body");
          13         Book b3 = new Book("Finding Emo");
          14 
          15         TreeSet<Book> tree = new TreeSet<Book>();
          16 
          17         tree.add(b1);
          18         tree.add(b2);
          19         tree.add(b3);
          20         tree.add(b3);
          21         System.out.println(tree);
          22     }
          23 
          24 }
          25 
          26 package collection;
          27 
          28 
          29 public class Book implements Comparable<Book> {
          30     String title;
          31 
          32     public Book(String t) {
          33         title = t;
          34     }
          35 
          36     @Override
          37     public int compareTo(Book o) {
          38         return title.compareTo(o.title);
          39     }
          40 
          41     @Override
          42     public String toString() {
          43         return title;
          44     }
          45 
          46 }



            TreeSet的排序功能也是通過實現Comparator或Comparable來完成的。要么是TreeSet集合中的元素實現了Comparable,要么是用重載的Comparator作為參數來創建TreeSet。


            回復  更多評論
            
          # re: 學習集合與泛型 2008-07-10 21:50 | BlueSunshine
          五 泛型

          1,泛型中的‘萬用字符’:

          <T extends  Comparable> :表示T是實現了Comparable的類型(在‘泛型’中extends表示extends或者implement)

          <? extends T> :表示必須是T或者T的父型

          ArrayList<? extends Animal> :以實現或繼承Animal的類型為元素類型的ArrayList

          2,相同功能的另一種語法:

          public <T extends Animal> void takeThing(ArrayList<T> list);

          等同于:public void takeThing(ArrayList<? extends Animal> list);   回復  更多評論
            
          # re: 學習集合與泛型 2009-10-16 22:47 | 初學生
          @BlueSunshine
          前輩
          <? extends T> :表示必須是T或者T的父型
          怎么不是子型
            回復  更多評論
            
          主站蜘蛛池模板: 含山县| 西乌| 石林| 剑阁县| 綦江县| 喀喇沁旗| 尖扎县| 东台市| 兰溪市| 玛沁县| 宕昌县| 景宁| 迁西县| 阿合奇县| 准格尔旗| 吉木萨尔县| 周至县| 琼海市| 临澧县| 林甸县| 霞浦县| 若羌县| 西林县| 盐源县| 常熟市| 景泰县| 长武县| 开化县| 南木林县| 安阳市| 子洲县| 平顺县| 瑞金市| 临夏县| 曲阳县| 松溪县| 山东省| 郴州市| 新邵县| 佛山市| 潞西市|