Delphi中的THashTable

在Delphi中,Inifiles单元中有一个TStringHash的类,不过它的Value仅支持Integer(其实也不是问题,有其它类型可以将变量变为Pointer),有点不舒服,今天没事做就把它替换为variant了,其中Key的名称大小写无关,就是为了加快开发速度!

使用Hashtable,查找和删除复杂度都是常数级别的!

type
  PPHashItem = ^PHashItem;
  PHashItem = ^THashItem;
  THashItem = record
    Next: PHashItem;
    Key: String;
    Value: Variant;
  end;
  THashTable = class
  private
    Buckets: array of PHashItem;
  protected
    function Find(const Key: String): PPHashItem;
    function HashOf(const Key: String): Cardinal; virtual;
  public
    constructor Create(Size: Cardinal = 256);
    destructor Destroy; override;
    procedure Put(const Key: String; Value: Variant);
    procedure Clear;
    procedure Remove(const Key: String);
    function Modify(const Key: String; Value: Variant): Boolean;
    function Get(const Key: String): Variant;
    function ContainKey(const Key: String):boolean;
  end;
procedure THashTable.Clear;
var
  I: Integer;
  P, N: PHashItem;
begin
  for I := 0 to Length(Buckets) - 1 do
  begin
    P := Buckets[I];
    while P <> nil do
    begin
      N := P^.Next;
      Dispose(P);
      P := N;
    end;
    Buckets[I] := nil;
  end;
end;
function THashTable.ContainKey(const Key: String): boolean;
var
  P: PHashItem;
begin
  P := Find(Key)^;
  if P <> nil then
  begin
    Result := True;
  end
  else
    Result := False;
end;
constructor THashTable.Create(Size: Cardinal);
begin
  inherited Create;
  SetLength(Buckets, Size);
end;
destructor THashTable.Destroy;
begin
  Clear;
  inherited Destroy;
end;
function THashTable.Find(const Key: String): PPHashItem;
var
  Hash: Integer;
begin
  Hash := HashOf(Key) mod Cardinal(Length(Buckets));
  Result := @Buckets[Hash];
  while Result^ <> nil do
  begin
    if Result^.Key = Key then
      Exit
    else
      Result := @Result^.Next;
  end;
end;
function THashTable.Get(const Key: String): Variant;
var
  P: PHashItem;
begin
  P := Find(AnsiUpperCase(Key))^;
  if P <> nil then
    Result := P^.Value
  else
    Result := -1;
end;
function THashTable.HashOf(const Key: String): Cardinal;
var
  I: Integer;
begin
  Result := 0;
  for I := 1 to Length(Key) do
    Result := ((Result shl 2) or (Result shr (SizeOf(Result) * 8 - 2))) xor
      Ord(Key[I]);
end;
function THashTable.Modify(const Key: String; Value: Variant): Boolean;
var
  P: PHashItem;
begin
  P := Find(Key)^;
  if P <> nil then
  begin
    Result := True;
    P^.Value := Value;
  end
  else
    Result := False;
end;
procedure THashTable.Put(const Key: String; Value: Variant);
var
  Hash: Integer;
  Bucket: PHashItem;
begin
  Hash := HashOf(AnsiUpperCase(Key)) mod Cardinal(Length(Buckets));
  New(Bucket);
  Bucket^.Key := AnsiUpperCase(Key);
  Bucket^.Value := Value;
  Bucket^.Next := Buckets[Hash];
  Buckets[Hash] := Bucket;
end;
procedure THashTable.Remove(const Key: String);
var
  P: PHashItem;
  Prev: PPHashItem;
begin
  Prev := Find(Key);
  P := Prev^;
  if P <> nil then
  begin
    Prev^ := P^.Next;
    Dispose(P);
  end;
end;

使用:

var
  Demo:THashTable;
begin
  Demo:=THashTable.Create();
  try
    Demo.Put(‘id‘,1);
    ShowMessage(Demo.Get(‘id‘));
  finally
    Demo.Free;
  end;
end;

参考:http://www.cnblogs.com/key-ok/p/3358929.html

时间: 2024-10-11 04:07:52

Delphi中的THashTable的相关文章

delphi中的Format函数详解

首先看它的声明:[[email protected]][@21ki!] function Format(const Format: string; const Args: array of const): string; overload;[[email protected]][@21ki!] 事实上Format方法有两种形式,另外一种是三个参数的,主要区别在于它是线程安全的,[[email protected]][@21ki!]但并不多用,所以这里只对第一个介绍:[[email protect

老陈---谈Delphi中SSL协议的应用[转]

摘要:本文主要介绍如何在Delphi中使用SSL协议.一共分为七个部分:(1)SSL协议是什么?(2)Delphi中如何使用SSL协议?(3)SSL客户端编程实例.(4)SSL服务端编程实例.(5)SSL证书编程实例.(6)中间人欺骗实例.(7)其它.本文作者同时有一个用SSL协议编写的作品叫SSLPROXY,感兴趣的读者可以从作者主页http://www.138soft.org下载. 一:SSL协议是什么?  SSL是一种加密传输协议.引用网上一段话:SSL 是Secure socket La

Delphi中Android运行和JNI交互分析

Androidapi.JNIBridge负责和JNI交互.,既然要交互,那么首先就是需要获得JNI的运行环境,Android本身内置的就有一个Java(Dalvik)虚拟机.所以这个第一步就肯定是要这个虚拟机和我们当前的运行线程环境关联.这时候Androidapi.JNIBridge中的TJNIResolver就出场了.GetJNIEnv这个函数就是, [delphi] view plaincopy class function TJNIResolver.GetJNIEnv: PJNIEnv;

Delphi中的消息处理

1.windows的消息驱动体系  在windows系统中,消息传递是实现对乡间通信和控制的主要手段.可以额系统都以消息驱动的方式工作.系统中发生的用户输入操作.显示信息的改变.系统环境参数变化等所有时间都以系统定义消息的形式出现在相关的应用程序和窗口.所以程序设计的主要任务就是为这些消息的处理设计代码. 在应用程序中,发送者可以通过发送消息要求接收者完成相应的处理.当程序运行时,windows系统为每个应用程序实例建立一个消息队列,一次保存发送给该程序实例的消息,在应用程序的主控部分,需要设置

关于Delphi中的字符串的详细分析

关于Delphi中的字符串的详细分析 只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(Short String) 长字符串(Long String) 宽字符串(Wide String) 零结尾字符串(Null-Terminated String).PChar和字符数组 1.短字符串(Short String) 固 定长度,最大字符数个数为255,短字符串也成为长度字节(Length-byt

Delphi中多线程用消息实现VCL数据同步显示

Delphi中多线程用消息实现VCL数据同步显示 Lanno Ckeeke 2006-5-12 概述: delphi中严格区分主线程和子主线程,主线程负责GUI的更新,子线程负责数据运算,当数据运行完毕后,子线程可以向主线程式发送消息,以便通知其将VCL中的数据更新. 实现: 关键在于消息的发送及接收.在消息结构Tmessage中wParam和lParam类型为Longint,而指针类型也定义为Longint,可以通过此指针来传递自己所感兴趣的数据.如传递字符数组: 数组定义: const MA

Delphi 中的 procedure of object

其实要了解这些东西,适当的学些反汇编,WINDOWS内存管理机制,PE结构,看下李维的VCL架构剖析可以很好理解type TMyEvent = procedure of object;这是一种数据类型的定义,他定义了一个可以在类中使用的函数类型区别于type TMyProc = procedure; TMyEvent 和 TMyProc 都定义了一个函数类型,他们的差别是,TMyProc 不可以用在类中定义事件,TMyEvent 却可以. 如果你想知道问什么,那就需要深入了解事件类型以及函数类型

[转]Delphi中,让程序只运行一次的方法

program onlyRunOne; uses Forms,Windows,SysUtils, Dialogs, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} var myMutex:HWND; begin myMutex:=CreateMutex(nil,false,'11111'); //名称只能全系统唯一. if WaitForSingleObject(myMutex,0)<>wait_TimeOut then begin Application.I

在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程!(更好的管理异常)

在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程! 如果直接使用Win32的API函数CreateThread()创建多个线程,也是可以创建的.但是,你应该明白,在每个线程中动态分配和销毁内存块,是需要同步保护的.Delphi语言中有一个在使用多线程环境下至关重要的全局变量IsMultiThread,系统在进行内存分配的时候,根据IsMultiThread变量值判断当前是否使用在多线程环境下,如果该变量为True,哪么,系统在分配和销毁内存的