THashedStringList对象

在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;  
    从中可以看出THashedStringList类继承自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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值