程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi2009中容器類簡介

Delphi2009中容器類簡介

編輯:Delphi

Delphi2009中容器類簡介:

1.TList類:

一個可以存儲指針的容器類,提供了一系列的方法和屬性來添加,刪除,重排,定位,存取和排序容器中的類,它是基於數組的機制來實現的容器,比較類似於C++中的Vector和Java中的ArrayList,TList 經常用來保存一組對象列表,基於數組實現的機制使得用下標存取容器中的對象非常快,但是隨著容器中的對象的增多,插入和刪除對象速度會直線下降,因此不適合頻繁添加和刪除對象的應用場景。

屬性 描述 Count: Integer; 返回列表中的項目數 Items[Index: Integer]: Pointer; default 通過以0為底的索引下標直接存取列表中的項目 方法 類型 描述 Add(Item: Pointer): Integer; 函數 用來向列表中添加指針 Clear; 過程 清空列表中的項目 Delete(Index: Integer); 過程 刪除列表中對應索引的項目 IndexOf(Item: Pointer): Integer; 函數 返回指針在列表中的索引 Insert(Index: Integer; Item: Pointer); 過程 將一個項目插入到列表中的指定位置 Remove(Item: Pointer): Integer; 函數 從列表中刪除指針 名稱 類型 描述 Capacity: Integer; property 可以用來獲取或設定列表可以容納的指針數目 Extract(Item: Pointer): Pointer; function Extract 類似於Remove 可以將指針從列表中刪除,不同的是返回被刪除的指針。  Exchange(Index1, Index2: Integer); procedure 交換列表中兩個指針 First: Pointer; function 返回鏈表中的第一個指針 Last: Pointer; function 返回鏈表中最後一個指針 Move(CurIndex NewIndex: Integer); procedure 將指針從當前位置移動到新的位置 Pack; procedure 從列表中刪除所有nil指針 Sort(Compare: TListSortCompare); procedure 用來對鏈表中的項目進行排序,可以設定Compare參數為用戶定制的排序函數

測試代碼:

unitUnit1;
interface
uses
 Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
 Dialogs,StdCtrls;
type
 TForm1=class(TForm)
  Edit1:TEdit;
  procedureFormCreate(Sender:TObject);
 private
  {Privatedeclarations}
  type
   TMyRec=record
    Id:Integer;
    Name:String;
    Age:Integer;
  end;
  PTMyRec=^TMyRec;
 public
  {Publicdeclarations}
 end;
var
 Form1:TForm1;
implementation
{$R*.dfm}
procedureTForm1.FormCreate(Sender:TObject);
var
 PsnInfo:PTMyRec;
 PsnList:TList;
begin
 PsnList:=TList.Create;
 new(PsnInfo);
 PsnInfo^.Id :=1;
 PsnInfo^.Name:='ShenBin';
 PsnInfo^.Age :=28;
 PsnList.Add(PsnInfo);
 PsnList.Add(PsnInfo);
 ShowMessage(IntToStr(PsnList.Count));
end;
end.

更多測試代碼可參閱:http://www.cnblogs.com/del/archive/2007/12/29/1019566.html

2.TObjectList 類

TObjectList 類直接從TList 類繼承,可以作為對象的容器。

不同於TList類,TObjectList類的Add, Remove, IndexOf, Insert等方法都需要傳遞TObject對象作為參數,由於有了編譯期的強類型檢查,使得TObjectList比TList更適合保存對象。此外TObjectList對象有OwnsObjects屬性。當設定為True (默認值),同TList類不同,TObjectList對象將銷毀任何從列表中刪除的對象。無論是調用Delete, Remove, Clear 方法,還是釋放TObjectList對象,都將銷毀列表中的對象。有了TObjectList類,我們就再也不用使用循環來釋放了對象。這就避免了釋放鏈表對象時,由於忘記釋放鏈表中的對象而導致的內存洩漏。另外要注意的是OwnsObjects屬性不會影響到Extract方法,TObjectList的Extract方法行為類似於TList,只是從列表中移除對象引用,而不會銷毀對象。

TObjectList 對象還提供了一個FindInstanceOf 函數,可以返回只有指定對象類型的對象實例在列表中的索引。如果AExact 參數為True,只有指定對象類型的對象實例會被定位,如果AExact 對象為False,AClass 的子類實例也將被定位。AStartAt 參數可以用來找到列表中的多個實例,只要每次調用FindInstanceOf 函數時,將起始索引加1,就可以定位到下一個對象,直到FindInstanceOf 返回-1。下面是代碼示意:

var
 idx:Integer;
begin
 idx:=-1;
 repeat
  idx:=ObjList.FindInstanceOf(TMyObject,True,idx+1);
  ifidx>=0then 
   ... 
 until(idx<0);
end;

3.TComponentList 類

注意TComponentList 是從TObjectList類繼承出來的,它的Add, Remove, IndexOf, Insert和 Items 方法調用都使用TComponent 類型的參數而不再是TObject類型,因此適合作為TComponent對象的容器。TComponentList 類還有一個特殊的特性,就是如果鏈表中的一個組件被釋放的話,它將被自動的從TComponentList 鏈表中刪除。這是利用TComponent的FreeNotification方法可以在組件被銷毀時通知鏈表,這樣鏈表就可以將對象引用從鏈表中刪除的。

4.TClassList 類

不同於前面兩個類,這個類繼承於TList的類只是將Add, Remove, IndexOf, Insert和Items 調用的參數從指針換成了TClass元類類型。

5.TOrderedList, TStack和TQueue 類

要注意雖然TOrderedList 並不是從TList繼承的,但是它在內部的實現時,使用了TList來儲存指針。另外注意TOrderedList類的PushItem 過程是一個抽象過程,所以我們無法實例化 TOrderedList 類,而應該從TOrderedList繼承新的類,並實現抽象的PushItem方法。TStack 和 TQueue 正是實現了PushItem抽象方法的類, 我們可以實例化TStack 和TQueue類作為後進先出的堆棧 (LIFO)和先進先出的隊列(FIFO)。下面是這兩個的的方法使用說明:

· Count 返回列表中的項目數。

· AtLeast 可以用來檢查鏈表的大小,判斷當前列表中的指針數目是否大於傳遞的參數值,如果為True表示列表中的項目數大於傳來的參數。

· 對於TStack類Push 方法將指針添加到鏈表的最後,對於TQueue類Push 方法則將指針插入到鏈表的開始。

· Pop返回鏈表的末端指針,並將其從鏈表中刪除。

· Peek返回鏈表的末端指針,但是不將其從鏈表中刪除。

6.TObjectStack和TObjectQueue類

這兩個類只是TStack和TQueue 類的簡單擴展,在鏈表中保存的是TObject的對象引用,而不是簡單的指針。

7.TIntList 類

到目前為止,我們看到的容器類中保存的都是指針或者對象引用(對象引用其實也是一種指針)。

那麼我們能不能在鏈表中保存原生類型,如Integer,Boolean或者Double等呢。下面的我們定義的類TIntList 類就可以在鏈表中保存整數,這裡我們利用了整數和指針都占用4個字節的存儲空間,所以我們可以直接將指針映射為整數。

8.TStrings類

出於效率的考慮,Delphi並沒有象C++和Java那樣將字符串定義為類,因此TList本身不能直接存儲字符串,而字符串列表又是使用非常廣泛的,為此Borland提供了TStrings類作為存儲字符串的基類,應該說是它除了TList類之外另外一個最重要的Delphi容器類。

要注意的是TStrings類本身包含了很多抽象的純虛的方法,因此不能實例化後直接使用,必須從TStrings類繼承一個基類實現所有的抽象的純虛方法來進行實際的字符串列表管理。雖然TStrings類本身是一個抽象類,但是它應該說是一個使用了Template模式的模版類,提供了很多事先定義好的算法來實現添加添加、刪除列表中的字符串,按下標存取列表中的字符串,對列表中的字符串進行排序,將字符串保存到流中。將每個字符串同一個對象關聯起來,提供了鍵-值對的關聯等等。

因為TStrings類本身是個抽象類,無法實例化,因此Delphi提供了一個TStringList的TStrings的子類提供了TStrings類的默認實現,通常在實際使用中,我們都應該使用TStringList類存儲字符串列表,代碼示意如下:

var TempList:TStrings;
begin
 TempList:=TStringList.Create;
 try
  TempList.Add('字符串1');
  …
 finally
  TempList.Free;
 end;
end;

TStrings類的應用非常廣泛,很多VCL類的屬性都是TStrings類型,比如TMemo組件的Lines屬性,TListBox的Items屬性等等。下面將介紹一下TStrings類的常見用法。

9.TStrings類的常見的用法

根據下標存取列表中的字符串是最常見的一種操作,用法示意如下:

StringList1.Strings[0] := '字符串1';

注意在Delphi中,幾乎所有的列表的下標都是以0為底的,也就是說Strings[0]是列表中的第一個字符串。另外,由於Strings屬性是字符串列表類的默認屬性,因此可以省略Strings,直接用下面的簡便方法存取字符串:

StringList1[0] := '字符串1';

定位一個列表中特定的字符串的位置,可以使用IndexOf方法,IndexOf方法將會返回在字符串列表中的第一個匹配的字符串的索引值,如果沒有匹配的字符串則返回-1。比如我們可以使用IndexOf方法來察看特定文件是否存在於文件列表框中,代碼示意如下:

if FileListBox1.Items.IndexOf('TargetFileName') > -1 ...

有一點不方便的是TStrings類沒有提供一個方法可以查找除了第一個匹配字符串外其他同樣匹配的字符串的索引,只能是自己遍歷字符串列表來實現,這點不如C++中的模版容器類以及相關的模版算法強大和方便。

下面是一個遍歷字符串列表的示意,代碼遍歷列表框中的所有字符串,並將其全部轉化為大寫的字符串:

procedure TForm1.Button1Click(Sender: TObject);var Index: Integer;
begin
 for Index := 0 to ListBox1.Items.Count - 1 do  
ListBox1.Items[Index] := UpperCase(ListBox1.Items[Index]);
end;

前面我們看到了,要想向字符串列表中添加字符串,直接使用Add方法就可以了,但是Add方法只能將字符串加入到列表的末尾,要想在列表的指定位置添加字符串,需要使用Insert方法,下面代碼在列表的索引為2的位置添加了字符串:

StringList1.Insert(2, 'Three');

如果要想將一個字符串列表中的所有字符串都添加到另一個字符串列表中,可以使用AddStrings方法,用法如下:

StringList1.AddStrings(StringList2); 

要想克隆一個字符串列表的所有內容,可以使用Assign方法,例如下面的方法將Combox1中的字符串列表復制到了Memo1中:

Memo1.Lines.Assign(ComboBox1.Items);

要注意的是使用了Assign方法後,目標字符串列表中原有的字符串會全部丟失。

10.THashedStringList類

一般來說,通過鍵來查找值最簡單的辦法是遍歷列表對列表中的鍵進行比較,如果相等則獲取相應的鍵值。但是這種簡單的辦法也是效率最差的一種辦法,當列表中的項目比較少時,這種辦法還可以接受,但是如果列表中項目非常多的話,這種方法會極大的影響軟件的運行速度。 這時我們可以使用哈希表來快速的通過鍵值來存取列表中的元素。由於本書並不是一本數據結構和算法的書,因此我無意在這裡討論哈希表背後的理論知識,我們只要知道哈希可以通過鍵快速定位相應的值就可以了,對此感興趣的非計算機專業的人可以去察看相關的書,這裡就不贅述了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved