標籤:
Delphi在在IniFiles 單元中定義了THashedStringList類:
THashedStringList = class(TStringList)
private FValueHash: TStringHash;
FNameHash: TStringHash;
FValueHashValid: Boolean;
FNameHashValid: Boolean;
procedure UpdateValueHash;
procedure UpdateNameHash;
protected procedure Changed; override;
public destructor Destroy; override;
function IndexOf(const S: string): Integer; override;
function IndexOfName(const Name: string): Integer; override;
end;
從中可以看出T HashedStringList類繼承自TStringList,所以保留了TStringList的方法,但TStringList類是使用數組以線性方式儲存所有子項的,所以無論使用其IndexOf方法還是IndexOfName方法都是使用線性尋找法,這種查尋方法當資料量比較大時其查詢是非常低。
THashedStringList類中添加了兩個TStringHash私人成員,分別用來存放對其子項鍵名雜湊表和索引值雜湊表。當調用其 IndexOf方法或是IndexOfName方法時,此類會首先檢查是否已經為索引值或是鍵名建立雜湊表,如果沒有,則建立之,否則直接使用雜湊演算法時行尋找。
function THashedStringList.IndexOf(const S: string): Integer;
begin UpdateValueHash; //建立索引值雜湊表
if not CaseSensitive then
Result := FValueHash.ValueOf(AnsiUpperCase(S))
else
Result := FValueHash.ValueOf(S);
end;
function THashedStringList.IndexOfName(const Name: string): Integer;
begin UpdateNameHash; //建立健名雜湊表
if not CaseSensitive then
Result := FNameHash.ValueOf(AnsiUpperCase(Name)) else
Result := FNameHash.ValueOf(Name); end;
當資料量不是很大時,如幾百、幾千時雜湊演算法的優勢並不是很明顯,但是隨著資料量在增大,其效能的提升是相當可觀的。所以如果需要使用TStringList儲存大資料量時,請使用THashedStringList代替。
舉例說明:
- unit Unit1;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls;
-
- type
- TForm1 = class(TForm)
- Button1: TButton;
- Button2: TButton;
- procedure Button1Click(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure Button2Click(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
-
- var
- Form1: TForm1;
-
- implementation
-
- {$R *.dfm}
-
- uses
- IniFiles; //THashedStringList 來自 IniFiles 單元
- var
- Hash: THashedStringList;
-
- { THashedStringList 繼承自 TStringList, 只是覆蓋了 IndexOf、IndexOfName 兩個方法以增加效率;
- 如果注重效率而不需要太多功能, 可以使用 TStringHash, 它是直接從 TObject 繼承的數組鏈表 }
-
-
- //建立雜湊表
- procedure TForm1.FormCreate(Sender: TObject);
- var
- i: Integer;
- begin
- Hash := THashedStringList.Create;
-
- for i := 97 to 122 do
- begin
- Hash.Add(Chr(i) + ‘=‘ + IntToStr(i));
- end;
-
- ShowMessage(Hash.Text);
- {
- 構建結果:
- a=97
- b=98
- c=99
- d=100
- e=101
- f=102
- g=103
- h=104
- i=105
- j=106
- k=107
- l=108
- m=109
- n=110
- o=111
- p=112
- q=113
- r=114
- s=115
- t=116
- u=117
- v=118
- w=119
- x=120
- y=121
- z=122
- }
- end;
-
- //檢索雜湊表
- procedure TForm1.Button1Click(Sender: TObject);
- var
- i: Integer;
- begin
- i := Hash.IndexOf(‘z=122‘);
- ShowMessage(IntToStr(i)); //25
-
- i := Hash.IndexOfName(‘z‘);
- ShowMessage(IntToStr(i)); //25
- end;
-
- //基本操作
- procedure TForm1.Button2Click(Sender: TObject);
- begin
- Hash.Values[‘a‘] := ‘65‘; //賦值
- Hash.ValueFromIndex[0] := ‘65‘; //用索引賦值
-
- ShowMessage(Hash.Values[‘z‘]); //122, 取值
- ShowMessage(Hash.ValueFromIndex[25]);//122, 用索引取值
-
- {其他動作參加 TStringList}
- end;
-
- procedure TForm1.FormDestroy(Sender: TObject);
- begin
- Hash.Free;
- end;
-
- end.
Delphi THashedStringList用法