JAVA

          人生若只如初見,何事秋風悲畫扇。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            50 隨筆 :: 25 文章 :: 157 評論 :: 0 Trackbacks
                在Java中有許多的容器集合。初一看起來有些糊涂,特別是對剛接觸Java來說(至少我當初就是這樣的)!其實稍微細心,深入一點點就會發現原來一切都是有規律的。我想別的事情也會是如此。
                 Java中的容器,接口都是由一些接口,抽象類及它們的實現類所組成。而它們全部封裝在java.util
          包中。


          1:Collection接口。

                 大多數的集合都實現了此接口,它基本方法是add(沒有get()方法,實現類中可能有如Arrylist),添加一對象。添加成功則返回true ,否則返回false。這是與Map不同的地方。還有一些常用的方法如iterator(),size(),toArray()(注:toArray()是返回一對象----object數組,而Arrays----也是java.util下的一個類,有一個asList方法它們通常認為是各集合之間轉換的橋梁)等等!具體用法可以參考API文檔。


          2:Map(映射)
                 Map接口跟Collection接口實際上沒有半點關系。集合中的每一個元素都包含一對鍵對對象和值對象,集合中沒有重復的鍵對象,值對象可以重復。它的有些實現類能對集合中的鍵對象進行排序。與Collection截然不同的是,它其中所存取的是一些值與名相對應的數據。也就是一個Key對應一個Value的方式來存儲。所以它就有與之對應的一些方法如:put (K key, V value)等等,更多可以參考API文檔。

          3:List(列表)
                集合中的對象按索引位置排序,可以有重復對象,允許按照對象在集合中的索引位置檢索對象

          4:Set(集)
                集合中的對象中按特定的方式排序,并且沒有重復對象。它的有些實現類能對集合中的對象
          按特定的方式排序

          5:迭代器:Iterator
                 它是一個接口,只有三個方法hasnext(),next(),remove()只有最后一個是可選的,也就是remove()是可選(在實現的時候)。其可選性也意味著它的實現類中,remove方法是可有可無的。例如,若有一個如下的List 實例。
                  
              Arrylist al = new Arrylist();
              Object[] ob 
          = al.toArray();
              List list 
          = Arrays.asList(ob);
              Iterator itor 
          = list.iterator();
              itor.remove();      
          //Error 

                  當調用Ierator itr = list.iterator()方法返回一迭代器的時候,便不支持remove方法,所以當你再使用irt.remove()時程序就是異常!

                  使用此迭代器要注意的是remove()方法。它所刪除的是指指針(暫這么叫著)上次所移經過的位置(Removes from the underlying collection the last element returned by the iterator (optional operation).)。我個人覺得有點象在JDBC中的ResultSet rs = ....;rs.last();rowsCount=rs.getRow();類似呢。
                  前面所講的,由于clollection提供了iterator()方法,所以迭代器是很容易實現的!

          6:常用實現類的一些繼承關系:

                  Collections,它是Java.util下的一個類。它為我們提供了許多有用的方法,如sort(...),max()等其具體用法可以參考API文檔,比如sort(List list);中list內的所有元素都必須實現Comparable接口(All elements in the list must implement the Comparable interface)。

                
          Arrylist ,它是List接口的實現類,而List則是繼承于Collection。
                 LinkedList,它也是間接對Colections的實現。用linkedlist的一些方法如addfirst(),removefirst(),addlast()等等可以用來實現如C中的堆棧,鏈表。(對于頻繁使用插入與刪除操作使用linkedlist是個不錯的選擇,對于經常進行索引操作則arrylist較好)。


                  HashSet(散列表),它實現了Set接口,也就意味著它的元素不能有重復值出現。并且在HashSet中沒有get()方法,但可以通過iterator()來實現。要注意的是假如要在HasSet中存放一些對象,那么你得重定義hashCode()與equals()二個方法來保不可以存放相同的內容的元素。對于hashcode()所返回的值,hashset用它來計算(通過特定的函數)該對象在內存中的存放位置;后者主要用來判斷二個對象的內容是否相等而返回對應的boolen型。
                 TreeSet,主要用來對元素進行排序操作,假如要往其中添加對象,則對象得實現
          Comparable接口。(假如不要對元素排序,則一般可選用HashSet)。

                 HashMap,主要特點是存放的一個鍵值對,一些有用的方法是可返回視圖(我覺得可以把它理解為一個集合)如:keyset(),values(),entyset()等。
                 關于對HashMap的小步深入理解:
                 HashMap是由鍵值對組成的,關于HashMap有二點要注意:1. 它的鍵只能是一個Object對象。 2. 當二個HashMap用equals方法比較時,實際的比較是它的Key,而與Value無關。

                 HashMap的主要特點是其底層的物理存放與查找用到了hash函數相關的原理。根據java窗口的查找原理,查找最快的應該是由數組經過工具類Arrays的Arrays.sort方法排序后,再用此工具類的Arrays.binarySearch方法進行查找。對于HashMap的數據查找就是用這個原理實現的,另外由于數組的致命缺點就是它是定長的,而HashMap卻是可以動態增加,所以查找過程其實不是將Key本身放在一個Object[]的數組中,而是將與Key有密切相關的信息做為索引Object[]數組的下標,然后根據此下標去Object[]數組中查找數據,這個所謂密切相關的信息就是通過Key.hashCode()函數所產生的數字。可想而知,當HashMap中的Key很多時,各Key所產生的hashCode肯定會有重合的現象發生,為了防止此情況發生,所以根據這個索引在數組中得到的對象并不是最終要查找的數據,查到的其實是一個list列表,在這列表中列出了由于HashMap中的Key通過散列后具有相同hashCode的全部對像。可以想像得到,這個列表中的對像應該是相當少的。對于對Object[]數據下下標定位后,就得到了這個列表,接下來equals函數粉墨登場了,若能返回true則表示此對象已經存在,這時HashMap會用新的值覆蓋舊值,若不存在則會做添加操作了。

                 在HashMap的初始化中,會涉及到二個比較重要的值,也是影響其性能的二個重要值:Object[]的長度(v1)、Object[]中實際已經存放了多少object對象(v2)。在我們初始化HashMap時會有:HashMap(int initialCapacity, float loadFactor) 這個方法,initialCapacity表示object[]的初始化長度,loadFactor表示允許此在Object[]存放數據的百分比(loadFactor=v2/v1),系統默認的是0.75(也就是可以存放占object[]數組3/4的數據)。當HashMap里的數據不斷增加時,它會自動地按數量級擴展Object[]的長度(應該盡量阻止Object[]的自動增加,這樣不但消費資源對于以后的查找、插入操作也不利)。
          HashMap結論:對于Key一定要實現hashCode() and equals方法,且盡量要讓hashCode散布得均勻。這樣才能充分利用Object[]數組,不然,會導致Object[]得不到充分利用,而在Object[index]具體對應的對象list列表中存放很多Key對像,而在list中進行查找操作是比較耗時的。

                 根據以上原理,HashMap的簡單實現:
          import java.util.*;
          import com.bruceeckel.util.*;

          public class SimpleHashMap extends AbstractMap {
            // Choose a prime number for the hash table
            // size, to achieve a uniform distribution:
            private static final int SZ = 997;
            private LinkedList[] bucket = new LinkedList[SZ];
            public Object put(Object key, Object value) {
              Object result = null;
              int index = key.hashCode() % SZ;
              if(index < 0) index = -index;
              if(bucket[index] == null)
                bucket[index] = new LinkedList();
              LinkedList pairs = bucket[index];
              MPair pair = new MPair(key, value);
              ListIterator it = pairs.listIterator();
              boolean found = false;
              while(it.hasNext()) {
                Object iPair = it.next();
                if(iPair.equals(pair)) {
                  result = ((MPair)iPair).getValue();
                  it.set(pair); // Replace old with new
                  found = true;
                  break;
                }
              }
              if(!found)
                bucket[index].add(pair);
              return result;
            }
            public Object get(Object key) {
              int index = key.hashCode() % SZ;
              if(index < 0) index = -index;
              if(bucket[index] == null) return null;
              LinkedList pairs = bucket[index];
              MPair match = new MPair(key, null);
              ListIterator it = pairs.listIterator();
              while(it.hasNext()) {
                Object iPair = it.next();
                if(iPair.equals(match))
                  return ((MPair)iPair).getValue();
              }
              return null;
            }
            public Set entrySet() {
              Set entries = new HashSet();
              for(int i = 0; i < bucket.length; i++) {
                if(bucket[i] == null) continue;
                Iterator it = bucket[i].iterator();
                while(it.hasNext())
                  entries.add(it.next());
              }
              return entries;
            }
            public static void main(String[] args) {
              SimpleHashMap m = new SimpleHashMap();
              Collections2.fill(m, Collections2.geography, 25);
              System.out.println(m);
            }
          } ///:~



                  TreeMap,它與HashMap差不多,不過是增加了對元素的排序功能,所以運行速度也就當然沒有hashmap來得快了。
                   以下是HashMap的一個實例(在對DB進行操作的時候很有用):
          HashMap valueMap;
          //this function just get key-value form DB ,defined by yourself
          valueMap = commondb.getElementStringValues("COMMENT_ID""content");
          java.util.Set tempkeys 
          = valueMap.entrySet();
                      java.util.Iterator keys 
          = tempkeys.iterator();
          while(keys.hasNext())
                          
          {
                              java.util.Map.Entry me
          =(java.util.Map.Entry)keys.next();
          String value 
          = me.getValue();
          int key = me.getKey();
          }


                 要注意的是entrySet()所返回的每一個元素都是Map.Entry類型的!(Returns a collection view of the mappings contained in this map. Each element in the returned collection is a Map.Entry.)      
           
                 Properties,繼承于hashtable。這個東東相信我們比較的喜歡了(在i18n,ant中可以是常見得很),呵呵。它可以從外部導入屬性文件。文件中的鍵值都是String類型。just like this:
                  
          company=study
          author
          =Jkallen
          copyright
          =2005-2006
                 
                   操作如下:
                 
          import java.util.*;
          import java.io.*;
          class PropTest
          {
              
          public static void main(String[] args)
              
          {
                  
          /*Properties pps=System.getProperties();
                  pps.list(System.out);
          */

                  Properties pps
          =new Properties();
                  
          try
                  
          {
                      pps.load(
          new FileInputStream("winsun.ini"));
                      Enumeration 
          enum=pps.propertyNames();
                      
          while(enum.hasMoreElements())
                      
          {
                          String strKey
          =(String)enum.nextElement();
                          String strValue
          =pps.getProperty(strKey);
                          
                          System.out.println(strKey
          +"="+strValue);
                      }

                  }

                  
          catch(Exception e)
                  
          {
                      e.printStackTrace();
                  }

              }

          }

                  其用法可以查看API文檔呢。

                  Java中的集合容器確實不少呢...其中有些我們也許一直都用不到,(我也是查看了些相關的資料再加上自己的一些想法整理了一下,希望對相關朋友有用!)可是重要的是知道我們在實現一個功能時應該選用哪種集合類來實現就OK了。

                 參考資料:JDK1.5文檔,Think in Java,孫鑫/張孝祥JAVA資料
          posted on 2006-01-12 00:21 Jkallen 閱讀(16895) 評論(9)  編輯  收藏 所屬分類: JEE學習

          評論

          # re: Java容器集合學習心得 2006-03-24 14:19 路過
          幸好有你! ::)  回復  更多評論
            

          # re: Java容器集合學習心得 2008-06-24 08:54 趙天宇
          寫得不錯。希望繼續發表一些這樣的文章!  回復  更多評論
            

          # re: Java容器集合學習心得 2008-06-30 11:15
          很好的東西,有時間我也多寫寫!!!  回復  更多評論
            

          # re: Java容器集合學習心得 2008-08-08 16:23 路過
          寫得相當好  回復  更多評論
            

          # re: Java容器集合學習心得 2009-03-03 19:47 快樂一休
          寫的很好呀~~~~  回復  更多評論
            

          # re: Java容器集合學習心得 2009-11-26 09:57 愛美女
          很有用 ,不錯 ~  回復  更多評論
            

          # re: Java容器集合學習心得 2010-12-10 17:04 java追求者
          值得珍藏和學習  回復  更多評論
            

          # re: Java容器集合學習心得 2012-06-18 09:35 丫的
          可以。。可是坑爹的沒學完!  回復  更多評論
            

          # re: Java容器集合學習心得 2014-01-23 16:10 cook5210
          謝謝樓主 謝的很詳細  回復  更多評論
            

          主站蜘蛛池模板: 澄迈县| 聂拉木县| 莲花县| 城口县| 平陆县| 华池县| 内乡县| 蒲城县| 翼城县| 宣恩县| 西畴县| 隆子县| 白水县| 南川市| 渝北区| 奇台县| 东兰县| 岳阳县| 遂平县| 海伦市| 子洲县| 揭阳市| 新巴尔虎右旗| 昔阳县| 双柏县| 信阳市| 朔州市| 虞城县| 巩留县| 巴彦县| 丁青县| 凉城县| 洛扎县| 南开区| 永修县| 邓州市| 隆子县| 水富县| 治多县| 教育| 河西区|