集合框架筆記(下)

       前面學習了ArrayList類,Collections類,迭代子Iterator,比較器Comparator;非常愉快。今天學習的內容包括,LinkedList類,HashSet類,TreeSet類,HashMap類,TreeMap類,以及Properties類。今天順便翻開以前的筆記看了看,發現反射API已經忘得差不多了,鬱悶。由此可見學習的時間一定要緊湊,一定要多複習,像我這樣認真記了筆記並做了總結的都忘記了,才一個月不到。汗。
      首先複習一下數據結構,堆棧(Stack)就像一個子彈夾,先放入的子彈後射出來(FILO);隊列就好像銀行排隊,先進的人先出來(FIFO)。
      在略說一下集合框架中的幾個接口類型,包括:
           List:通過迭代子來精確地控制元素的隨機訪問;
           Set:  不允許重複元素出現,
           Map:  存儲鍵值對,不允許相同的鍵出現。
     1.  LinkedList類:
           LinkedList它本身類似於一個雙向循環鏈表,可以實現棧,隊列,雙向隊列的功能,它常用的成員函數如下
           addFirst(),將某個元素加到鏈表頭;
           addLast(),將某個元素加到鏈表尾;
           getFirst(),查看隊頭元素;
           getLast(),查看隊尾元素;
           removeFirst(),刪除並返回隊頭元素;
           removeLast(),刪除並返回隊尾元素;
           實際上LinkedList和ArrayList是很相似的,但是卻各有用途,LinkedList更便於於添加和刪除操作,而ArrayList更加方便於隨機訪問。
     
     2.HashSet類:
           將元素存儲在一種稱爲“散列表”的結構中,以要存儲的元素爲自變量,通過散列函數的計算而得到其在散列中的存儲地址,如果散列表中的元素的個數達到總位置的某個比例(稱爲負載因子,默認爲0.75),將對自身進行擴容,並重新計算每個元素的位置,產生新的散列表,並且刪除原表。構造HashSet類的對象時,默認的容量是16個元素,負載因子默認爲0.75,當然,容量和負載因子都可以在構造時自己指定。
           因爲HashSet中不允許出現重複的因子,因而它必須存在一個判斷的標準,如何判斷兩個要加入哈希散列中的元素是否相等?HashSet判定的標準是依照這兩個因子產生的散列碼是否相等,散列碼會依照java.lang.object.hashCode()函數產生,因此這個函數必須被重寫,但是又不必我們程序員自己來實現這一技術,因爲各標準類型都重寫了hashCode(),我們只要有選擇地調用就可以了(注:這個散列碼實際上是依照內存地址產生的);而hashCode()函數和java.lang.object.equals()函數息息相關,因此equals函數也必須重寫,而且必須保證,用equals()比較相等的兩個元素,其產生的散列碼也必須相等。因而,必須注意,在欲放入hashSet中的類中必須同時重寫hashCode()和equals();
     3.TreeSet類
           放入其中的元素會按照自然順序進行排列,要求欲放入其中的類實現Comparable接口。當然,也可以在構造TreeSet對象時調用某個構造函數載入一個Comparator因子,這個在前面已經提到過,是java.util下的一個接口,我們又稱之爲比較器。
           HashSet性能要優越於TreeSet,而TreeSet實現了排序。
     4.HashMap類
          HashMap和前面提到的類都不同,他內部存儲的是鍵值對(key_value),一個鍵對應於一個值,不允許重複的鍵出現,但是允許值出現空值。
          常用的函數有
                put(key,value)  放入鍵值對
                get(key) 通過鍵獲得值
                Set keySet() 獲得所有鍵的視圖
                Collection values() 獲得所有值的視圖
                Set entrySet()  這個函數的用法是,先得到一個Set,然後將一個Iteratror關聯這個Set,然後利用next()獲得Set中的元素,將每個元素賦值給一個Map.Entry類型的量,這個Map.Entry類型中有函數getKey()和getValue()可以分別獲得鍵和值,爲了更好的說明,引用一段代碼如下
            HashMap hm=new HashMap();
     hm.put(1,"zhangsan");
     if(!hm.isEmpty())
     {
    Set s=hm.keySet();                  //返回鍵值
    Collection c=hm.values();           //返回值
    iteratorTool(s.iterator());
    iteratorTool(c.iterator());          //iteratorTool()這裏是我自定義的一個輸出函數
    Set end=hm.entrySet(); //這裏返回的set實際上是Map.entry
    Iterator it=end.iterator();
    while(it.hasNext())
    {
     Map.Entry xa=(Map.Entry)it.next();
     System.out.println(xa.getKey()+" "+xa.getValue());
              }
           }
          另外,在java.util包下,還有一個十分有用的properties,等學習了I/O操作以後再詳細的寫出來。
今天的總結就寫完啦,期間被人拉去打遊戲,耽誤了一點時間,不過不要緊啦。
下面是源代碼,爲了便於輸出,我自定義了一個iteratorTool()的函數,不管是要輸出什麼,只要獲得一個Iteratror作爲參數就可以了,這就是面向對象的威力啦。但是讓我百思不得其解的是,在第30行,本來這裏是應該要寫一個if else語句的,但是一旦寫了這樣的語句,編譯的時候會提示“缺少返回值”,讓我十分鬱悶。下面的源代碼我會註明一下,請高手們多多指正啦。
import java.util.*;
class Student implements Comparable //TreeSet必須實現該接口以按自然順序排列
{
 Student(int id,String name)
 {
  this.id=id;
  this.name=name;
 }
 int id;
 String name;
 public String toString()
 {
  return id+":"+name;
 }
 public int hashCode()
 {
  return this.name.hashCode();
 }
 public boolean equals(Object o)           //HashSet必須重寫hashCode()和equals()
 {
  Student s=(Student)o;
  if(id==s.id&&name==s.name)
        return true;
  else
        return false;
 }
  public int compareTo(Object p)
 {
    Student m=(Student)p;
    return name.compareTo(m.name);  //百思不得其解的地方,無法寫成if else
 }                      
}

class LinkedListTest
{
 public static void iteratorTool(Iterator i)
 {
  while(i.hasNext())
  {
   System.out.println(i.next());
  }
 }
 public static void main(String[] args)
 {
  //-----------------------以下爲LinkedList練習
  Student s1=new Student(2,"zhangsan");
  Student s2=new Student(3,"lisi");
  Student s3=new Student(4,"wangwu");
  LinkedList link=new LinkedList();
  //like Stack
  link.addFirst(s1);
  link.addFirst(s2);
  link.addFirst(s3);
  System.out.println("First in last out");
  while(link.size()>0)          //size()是成員函數,查詢元素個數
        System.out.println(link.removeFirst());
  
   //------------------------以下爲HashSet練習
   HashSet hash=new HashSet();
   Student s4=new Student(1,"zhangsan");
   Student s5=new Student(2,"zhangsan");
   hash.add(s1);       //如果s1未在哈希散列表中存在則添加
   hash.add(s2);
   hash.add(s3);
   hash.add(s4);
   hash.add(s5);       //事實上s5會添加失敗
   System.out.println("-------------------------------");
   System.out.println("Now,it's HashSet time");
   iteratorTool(hash.iterator());   //哈希表需要通過迭代器進行訪
   System.out.println("-------------------------------");
   System.out.println("Now,it's TreeSet time");
   TreeSet tree=new TreeSet();
   tree.add(s1);
   tree.add(s2);
   tree.add(s3);
   tree.add(s4);
   tree.add(s5);
   iteratorTool(tree.iterator());
   System.out.println("---------------------------------");
   System.out.println("Now it's HashMap time");
   HashMap hm=new HashMap();
   hm.put(1,"zhangsan");
   hm.put(2,"zhangsan");
   hm.put(2,"wangsan");
   if(!hm.isEmpty())
   {
    Set s=hm.keySet();                  //返回鍵值
    Collection c=hm.values();           //返回值
    System.out.println("the key summary");
    iteratorTool(s.iterator());
    System.out.println("the values summary");
    iteratorTool(c.iterator());
    Set end=hm.entrySet(); //這裏返回的set實際上是Map.entry
    Iterator it=end.iterator();
    System.out.println("--------------------------------");
    System.out.println("Test Map.Entry,");
    while(it.hasNext())
    {
     Map.Entry xa=(Map.Entry)it.next();
     System.out.println(xa.getKey()+" "+xa.getValue());
    }
   }
 }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章