注冊(cè) 登錄
Office中國(guó)論壇/Access中國(guó)論壇 返回首頁(yè)

ganlinlao的個(gè)人空間 http://m.mzhfr.cn/?230471 [收藏] [復(fù)制] [分享] [RSS]

日志

在Freebasic中使用集合類(泛型)(第一節(jié))

已有 1990 次閱讀2015-5-21 11:59 |個(gè)人分類:FreeBasic

接下來(lái),介紹的這個(gè)庫(kù),蠻有用的,它以類似java的集合類
包裝了freebasic的集合類,這樣便于在實(shí)際中使用。

第一節(jié):集合類基礎(chǔ)概念的了解
mdTypes 是一個(gè)模仿Java 類的 FreeBASIC 的集合類。
如果這些類在java中是泛型的集合類,那么FreeBasic也允許通過(guò)宏來(lái)實(shí)現(xiàn)某些類型的泛型
到目前為止,MdTypes提供的集合類,包括了一系列的集合對(duì)象:list和map等
list 類:
- md/util/mdCollection(T)
-- md/util/mdList(T)
---- md/util/mdVector(T)
------ md/util/mdStack(T)
-- md/util/mdSet(T)
-- md/util/mdQueue(T)

map 類:
- md/util/mdMap(K, V) (using inner class mdMapEntry(K, V))
--- md/util/mdDictionary(K, V)
----- md/util/mdHashtable(K, V)
------- md/util/mdProperties

要遍歷list類,下面這些迭代器是可用的:
- md/util/mdIterator(T)
--- md/util/mdArrayIterator(T)
- md/util/mdEnumeration(T)
對(duì)于象我這樣不熟悉java或c#的人來(lái)說(shuō),有必要對(duì)list,map等一些概念進(jìn)行適當(dāng)了解。
******************************************
接下來(lái)的知識(shí)點(diǎn)是Java集合類的基礎(chǔ)教程
*****************************************
Colleciton接口
   Collection是最基本的集合接口,一個(gè)Collection代表一組object,即Collection的元素(Elements)。一些collection允許相同的元素而另一些不行。一些能排序而另一些不行。Java不提供直接繼承自collection的類,java提供的類都是繼承collection的“子接口”如List和set。     
      所有實(shí)現(xiàn)collection接口的類都必須提供兩個(gè)標(biāo)準(zhǔn)的構(gòu)造函數(shù):無(wú)參數(shù)的構(gòu)造函數(shù)用于創(chuàng)建一個(gè)空的collection,有一個(gè)collection參數(shù)的構(gòu)造函數(shù)用于創(chuàng)建一個(gè)新的collection,這個(gè)新的collection與傳入的collection有相同的元素,后一個(gè)構(gòu)造函數(shù)允許用戶復(fù)制一collection。
       如何遍歷Collection中的每一個(gè)元素?不論Collection的實(shí)際類型如何,它都支持一個(gè)iterator()的方法,該方法返回一個(gè)迭代子,使用該迭代子即可逐一訪問(wèn)Collection中每一個(gè)元素。典型的用法如下:
    Iterator it = collection.iterator(); // 獲得一個(gè)迭代子
    while(it.hasNext()) {
      Object obj = it.next(); // 得到下一個(gè)元素
    }
由Collection接口派生的兩個(gè)接口是List和Set。
       Collection的方法:
       (1) 單元素添加、刪除操作:
             boolean add(Object o):將對(duì)象添加給集合
           boolean remove(Object o): 如果集合中有與o相匹配的對(duì)象,則刪除對(duì)象o
       (2) 查詢操作:
            int size() :返回當(dāng)前集合中元素的數(shù)量
            boolean isEmpty() :判斷集合中是否有任何元素
            boolean contains(Object o) :查找集合中是否含有對(duì)象o
            Iterator iterator() :返回一個(gè)迭代器,用來(lái)訪問(wèn)集合中的各個(gè)元素
       (3) 組操作 :作用于元素組或整個(gè)集合
            boolean containsAll(Collection c): 查找集合中是否含有集合c 中所有元素
           boolean addAll(Collection c) : 將集合c 中所有元素添加給該集合
           void clear(): 刪除集合中所有元素
           void removeAll(Collection c) : 從集合中刪除集合c 中的所有元素
           void retainAll(Collection c) : 從集合中刪除集合c 中不包含的元素
       (4) Collection轉(zhuǎn)換為Object數(shù)組 :
            Object[] toArray() :返回一個(gè)內(nèi)含集合所有元素的array
            Object[] toArray(Object[] a) :返回一個(gè)內(nèi)含集合所有元素的array。運(yùn)行期返回的array和參數(shù)a的型別相同,需要轉(zhuǎn)換為正確型別。

2、iterator接口:
         collection接口的iterator方法返回一個(gè)iterator。iterator接口方能以迭代方式逐個(gè)訪問(wèn)集合中各個(gè)元素,并安全的從collection中除去適當(dāng)?shù)脑亍?br>       (1)boolean hasNext()
           判斷是否存在另一個(gè)可訪問(wèn)的元素
      (2)object next()
           返回要訪問(wèn)的下一個(gè)元素。如果到達(dá)集合結(jié)尾則拋出NoSuchElementException異常
     (3)void Remove()
       刪除上次訪問(wèn)返回的對(duì)象。本方法必須緊跟在一個(gè)元素的訪問(wèn)后執(zhí)行。如果上次訪問(wèn)后合已被修改,方法將拋出IllegalStateException。
      “Iterator中刪除操作對(duì)底層Collection也有影響。”迭代器是故障快速修復(fù)(fail-fast)的。這意味著,當(dāng)另一個(gè)線程修改底層集合的時(shí)候,如果您正在用 Iterator 遍歷集合,那么,Iterator就會(huì)拋出 ConcurrentModificationException (另一種 RuntimeException異常)異常并立刻失敗

3、List接口:
           List是有序的Collection,使用此接口能夠精確的控制每個(gè)元素插入的位置。用戶能夠使用索引(元素在List中的位置,類似于數(shù)組下標(biāo))來(lái)訪問(wèn)List中的元素,這類似于Java的數(shù)組。和下面要提到的Set不同,List允許有相同的元素。
      List接口不但能夠?qū)α斜淼囊徊糠诌M(jìn)行處理,還添加了面向位置的操作。
      (1) 面向位置的操作包括插入某個(gè)元素或 Collection 的功能,還包括獲取、除去或更改元素的功能。在List 中搜索元素可以從列表的頭部或尾部開(kāi)始,如果找到元素,還將報(bào)告元素所在的位置 :
   void add(int index, Object element):
        在指定位置index上添加元素element
   boolean addAll(int index, Collection c):
        將集合c的所有元素添加到指定位置index
   Object get(int index):
        返回List中指定位置的元素
   int indexOf(Object o):
        返回第一個(gè)出現(xiàn)元素o的位置,否則返回-1
   int lastIndexOf(Object o):
        返回最后一個(gè)出現(xiàn)元素o的位置,否則返回-1
   Object remove(int index):
        刪除指定位置上的元素
   Object set(int index, Object element):
        用元素element取代位置index上的元素,并且返回舊的元素

       (2) List 接口不但以位置序列迭代的遍歷整個(gè)列表,還能處理集合的子集:
  ListIterator listIterator():
       返回一個(gè)列表迭代器,用來(lái)訪問(wèn)列表中的元素
   ListIterator listIterator(int index):
        返回一個(gè)列表迭代器,用來(lái)從指定位置index開(kāi)始訪問(wèn)列表中的元素
   List subList(int fromIndex, int toIndex):
       返回從指定位置fromIndex(包含)到toIndex(不包含)范圍中各個(gè)元素的列表視圖

   在“集合框架”中有兩種常規(guī)的 List 實(shí)現(xiàn):ArrayList 和 LinkedList。
使用哪一種取決于您特定的需要。如果要支持隨機(jī)訪問(wèn),而不必在除尾部的任何位置插入或除去元素, 那么,ArrayList 提供了可選的集合。但如果,您要頻繁的從列表的中間位置添加和除去元素,而 只要順序的訪問(wèn)列表元素,那么,LinkedList 實(shí)現(xiàn)更好。
“ArrayList 和 LinkedList 都實(shí)現(xiàn) Cloneable 接口,都提供了兩個(gè)構(gòu)造函數(shù),一個(gè)無(wú)參的,一個(gè)接受另一個(gè)Collection”
4.LinkedList類:
     LinkedList實(shí)現(xiàn)了List接口,允許null元素。此外LinkedList提供額外的get,remove,insert方法在 LinkedList的首部或尾部。這些操作使LinkedList可被用作堆棧(stack),隊(duì)列(queue)或雙向隊(duì)列(deque)。
  注意LinkedList沒(méi)有同步方法。如果多個(gè)線程同時(shí)訪問(wèn)一個(gè)List,則必須自己實(shí)現(xiàn)訪問(wèn)同步。一種解決方法是在創(chuàng)建List時(shí)構(gòu)造一個(gè)同步的List:
    List list = Collections.synchronizedList(new LinkedList(...));
LinkedList添加了一些處理列表兩端元素的方法。
       (1)void addFirst(Object o): 將對(duì)象o添加到列表的開(kāi)頭
           void addLast(Object o):將對(duì)象o添加到列表的結(jié)尾
       (2)Object getFirst(): 返回列表開(kāi)頭的元素
           Object getLast(): 返回列表結(jié)尾的元素
       (3)Object removeFirst(): 刪除并且返回列表開(kāi)頭的元素
           Object removeLast():刪除并且返回列表結(jié)尾的元素
       (4)LinkedList(): 構(gòu)建一個(gè)空的鏈接列表
           LinkedList(Collection c): 構(gòu)建一個(gè)鏈接列表,并且添加集合c的所有元素 。
5.ArrayList類:
ArrayList實(shí)現(xiàn)了可變大小的數(shù)組。
ArrayList封裝了一個(gè)動(dòng)態(tài)再分配的Object[]數(shù)組。每個(gè)ArrayList對(duì)象有一個(gè)capacity。
一個(gè)capacity表示存儲(chǔ)列表中元素的數(shù)組的容量。當(dāng)元素添加到ArrayList時(shí),它的capacity 在常量時(shí)間內(nèi)自動(dòng)增加。在向一個(gè)ArrayList對(duì)象添加大量元素的程序中,可使用 ensureCapacity方法增加capacity。這可以減少增加重分配的數(shù)量。
       (1) void ensureCapacity(int minCapacity):
            將ArrayList對(duì)象容量增加minCapacity
  (2) void trimToSize():
             整理ArrayList對(duì)象容量為列表當(dāng)前大小。使用這個(gè)操作減少ArrayList對(duì)象存儲(chǔ)空間。

Vector類
  Vector非常類似ArrayList,但是Vector是同步的。由Vector創(chuàng)建的Iterator,雖然和 ArrayList創(chuàng)建的Iterator是同一接口,但是,因?yàn)閂ector是同步的,當(dāng)一個(gè)Iterator被創(chuàng)建而且正在被使用,另一個(gè)線程改變了 Vector的狀態(tài)(例如,添加或刪除了一些元素),這時(shí)調(diào)用Iterator的方法時(shí)將拋出 ConcurrentModificationException,因此必須捕獲該異常。
Stack 類
  Stack繼承自Vector,實(shí)現(xiàn)一個(gè)后進(jìn)先出的堆棧。Stack提供5個(gè)額外的方法使得Vector得以被當(dāng)作堆棧使用;镜膒ush和pop 方法,還有peek方法得到棧頂?shù)脑兀琫mpty方法測(cè)試堆棧是否為空,search方法檢測(cè)一個(gè)元素在堆棧中的位置。Stack剛創(chuàng)建后是空棧。

set接口:(數(shù)學(xué)中的集合)
    Set是一種不包含重復(fù)的元素的Collection,即任意的兩個(gè)元素e1和e2都有e1.equals(e2)=false,Set最多有一個(gè)null元素。
  很明顯,Set的構(gòu)造函數(shù)有一個(gè)約束條件,傳入的Collection參數(shù)不能包含重復(fù)的元素。
  請(qǐng)注意:必須小心操作可變對(duì)象(Mutable Object)。如果一個(gè)Set中的可變?cè)馗淖兞俗陨頎顟B(tài)導(dǎo)致Object.equals(Object)=true將導(dǎo)致一些問(wèn)題。
set接口沒(méi)有引用新方法,所以set就是一個(gè)collection,只不過(guò)其行為不同。

7.Comparable接口和Comparator接口
  在“集合框架”中有兩種比較接口:Comparable接口和Comparator接口。像String和Integer等Java內(nèi)建類實(shí)現(xiàn) Comparable接口以提供一定排序方式,但這樣只能實(shí)現(xiàn)該接口一次。對(duì)于那些沒(méi)有實(shí)現(xiàn)Comparable接口的類、或者自定義的類,您可以通過(guò) Comparator接口來(lái)定義您自己的比較方式。
 Comparable接口
 在java.lang包中,Comparable接口適用于一個(gè)類有自然順序的時(shí)候。假定對(duì)象集合是同一類型,該接口允許您把集合排序成自然順序。
 int compareTo(Object o): 比較當(dāng)前實(shí)例對(duì)象與對(duì)象o,如果位于對(duì)象o之前,返回負(fù)值,如果兩個(gè)對(duì)象在排序中位置相同,則返回0,如果位于對(duì)象o后面,則返回正值

Map接口:
 請(qǐng)注意,Map沒(méi)有繼承Collection接口,Map提供key到value的映射。一個(gè)Map中不能包含相同的key,每個(gè)key只能映射一個(gè) value。Map接口提供3種集合的視圖,Map的內(nèi)容可以被當(dāng)作一組key集合,一組value集合,或者一組key-value映射。
(1) 添加、刪除操作:
  Object put(Object key, Object value):
將互相關(guān)聯(lián)的一個(gè)關(guān)鍵字與一個(gè)值放入該映像。如果該關(guān)鍵字已經(jīng)存在,那么與此關(guān)鍵字相關(guān)的新值將取代舊值。方法返回關(guān)鍵字的舊值,如果關(guān)鍵字原先并不存在,則返回 null
   Object remove(Object key):
從映像中刪除與key相關(guān)的映射
   void putAll(Map t):
將來(lái)自特定映像的所有元素添加給該映像
   void clear():
從映像中刪除所有映射
 “鍵和值都可以為null。但是,您不能把Map作為一個(gè)鍵或值添加給自身!
 (2) 查詢操作:
   Object get(Object key):
          得與關(guān)鍵字key相關(guān)的值,并且返回與關(guān)鍵字key相關(guān)的對(duì)象,如果沒(méi)有在該映像中找 到該關(guān)鍵字,則返回null
   boolean containsKey(Object key):
         判斷映像中是否存在關(guān)鍵字key
   boolean containsValue(Object value):
        判斷映像中是否存在值value
   int size():
       返回當(dāng)前映像中映射的數(shù)量
   boolean isEmpty():
        判斷映像中是否有任何映射
 (3) 視圖操作 :處理映像中鍵/值對(duì)組
   Set keySet(): 返回映像中所有關(guān)鍵字的視圖集
   Collection values():返回映像中所有值的視圖集
 Set entrySet(): 返回Map.Entry對(duì)象的視圖集,即映像中的關(guān)鍵字/值對(duì)

Hashtable類
  Hashtable繼承Map接口,實(shí)現(xiàn)一個(gè)key-value映射的哈希表。任何非空(non-null)的對(duì)象都可作為key或者value。
  添加數(shù)據(jù)使用put(key, value),取出數(shù)據(jù)使用get(key),這兩個(gè)基本操作的時(shí)間開(kāi)銷為常數(shù)。
Hashtable通過(guò)initial capacity和load factor兩個(gè)參數(shù)調(diào)整性能。通常缺省的load factor 0.75較好地實(shí)現(xiàn)了時(shí)間和空間的均衡。增大load factor可以節(jié)省空間但相應(yīng)的查找時(shí)間將增大,這會(huì)影響像get和put這樣的操作。
使用Hashtable的簡(jiǎn)單示例如下,將1,2,3放到Hashtable中,他們的key分別是”one”,”two”,”three”:
    Hashtable numbers = new Hashtable();
    numbers.put(“one”, new Integer(1));
    numbers.put(“two”, new Integer(2));
    numbers.put(“three”, new Integer(3));
  要取出一個(gè)數(shù),比如2,用相應(yīng)的key:
    Integer n = (Integer)numbers.get(“two”);
    System.out.println(“two = ” + n);
  由于作為key的對(duì)象將通過(guò)計(jì)算其散列函數(shù)來(lái)確定與之對(duì)應(yīng)的value的位置,因此任何作為key的對(duì)象都必須實(shí)現(xiàn)hashCode和equals方法。hashCode和equals方法繼承自根類Object,如果你用自定義的類當(dāng)作key的話,要相當(dāng)小心,按照散列函數(shù)的定義,如果兩個(gè)對(duì)象相同,即obj1.equals(obj2)=true,則它們的hashCode必須相同,但如果兩個(gè)對(duì)象不同,則它們的hashCode不一定不同,如果兩個(gè)不同對(duì)象的hashCode相同,這種現(xiàn)象稱為沖突,沖突會(huì)導(dǎo)致操作哈希表的時(shí)間開(kāi)銷增大,所以盡量定義好的hashCode()方法,能加快哈希表的操作。
  如果相同的對(duì)象有不同的hashCode,對(duì)哈希表的操作會(huì)出現(xiàn)意想不到的結(jié)果(期待的get方法返回null),要避免這種問(wèn)題,只需要牢記一條:要同時(shí)復(fù)寫(xiě)equals方法和hashCode方法,而不要只寫(xiě)其中一個(gè)。
  Hashtable是同步的。

HashMap類
  HashMap和Hashtable類似,不同之處在于HashMap是非同步的,并且允許null,即null value和null key。,但是將HashMap視為Collection時(shí)(values()方法可返回Collection),其迭代子操作時(shí)間開(kāi)銷和HashMap 的容量成比例。因此,如果迭代操作的性能相當(dāng)重要的話,不要將HashMap的初始化容量設(shè)得過(guò)高,或者load factor過(guò)低。

WeakHashMap類
  WeakHashMap是一種改進(jìn)的HashMap,它對(duì)key實(shí)行“弱引用”,如果一個(gè)key不再被外部所引用,那么該key可以被GC回收。

總結(jié):
 Collection 接口是一組允許重復(fù)的對(duì)象。
  • Set 接口繼承 Collection,但不允許重復(fù),使用自己內(nèi)部的一個(gè)排列機(jī)制。
  • List 接口繼承 Collection,允許重復(fù),以元素安插的次序來(lái)放置元素,不會(huì)重新排列。
  • Map接口是一組成對(duì)的鍵-值對(duì)象,即所持有的是key-value pairs。Map中不能有重復(fù)的key。擁有自己的內(nèi)部排列機(jī)制。
  容器中的元素類型都為Object。從容器取得元素時(shí),必須把它轉(zhuǎn)換成原來(lái)的類型。
        如果涉及到堆棧,隊(duì)列等操作,應(yīng)該考慮用List,對(duì)于需要快速插入,刪除元素,應(yīng)該使用LinkedList,如果需要快速隨機(jī)訪問(wèn)元素,應(yīng)該使用ArrayList。  
  要特別注意對(duì)哈希表的操作,作為key的對(duì)象要正確復(fù)寫(xiě)equals和hashCode方法。
  盡量返回接口而非實(shí)際的類型,如返回List而非ArrayList,這樣如果以后需要將ArrayList換成LinkedList時(shí),客戶端代碼不用改變。這就是針對(duì)抽象編程。

*****************************************************
以上內(nèi)容是java集合類的基礎(chǔ)教程
******************************************************

評(píng)論 (0 個(gè)評(píng)論)

facelist doodle 涂鴉板

您需要登錄后才可以評(píng)論 登錄 | 注冊(cè)

QQ|站長(zhǎng)郵箱|小黑屋|手機(jī)版|Office中國(guó)/Access中國(guó) ( 粵ICP備10043721號(hào)-1 )  

GMT+8, 2025-7-13 03:15 , Processed in 0.059573 second(s), 17 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

返回頂部