Delphi中的容器类

2016-02-19 14:42 31 1 收藏

下面是个超简单的Delphi中的容器类教程,图老师小编精心挑选推荐,大家行行好,多给几个赞吧,小编吐血跪求~

【 tulaoshi.com - 编程语言 】

  从Delphi 5开始VCL中增加了一个新的Contnrs单元,单元中定义了8个新的类,全部都是基于标准的TList 类。 

  TList 类

  TList 类实际上就是一个可以存储指针的容器类,提供了一系列的方法和属性来添加,删除,重排,定位,存取和排序容器中的类,它是基于数组的机制来实现的容器,比较类似于C++中的Vector和Java中的ArrayList,TList 经常用来保存一组对象列表,基于数组实现的机制使得用下标存取容器中的对象非常快,但是随着容器中的对象的增多,插入和删除对象速度会直线下降,因此不适合频繁添加和删除对象的应用场景。下面是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;functionExtract 类似于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参数为用户定制的排序函数

  TObjectList 类

  TObjectList 类直接从TList 类继承,可以作为对象的容器。TObjectList类定义如下: 

TObjectList = class(TList) ...public  constructor Create; overload;  constructor Create(AOwnsObjects: Boolean); overload;  function Add(AObject: TObject): Integer;  function Remove(AObject: TObject): Integer;  function IndexOf(AObject: TObject): Integer;  function FindInstanceOf(AClass: TClass;  AExact: Boolean = True; AStartAt: Integer = 0):  Integer;  procedure Insert(Index: Integer; AObject: TObject);  property OwnsObjects: Boolean;  property Items[Index: Integer]: TObject; default;end;

  不同于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);   if idx = 0 then   ...  until(idx  0);end;

  TComponentList 类

  Contnrs单元中还定义了TComponentList 类,类定义如下:

TComponentList = class(TObjectList) ...public  function Add(AComponent: TComponent): Integer;  function Remove(AComponent: TComponent): Integer;  function IndexOf(AComponent: TComponent): Integer;  procedure Insert(Index: Integer; AComponent: TComponent);  property Items[Index: Integer]: TComponent; default;end;

  注意TComponentList 是从TObjectList类继承出来的,它的Add, Remove, IndexOf, Insert和 Items 方法调用都使用TComponent 类型的参数而不再是TObject类型,因此适合作为TComponent对象的容器。TComponentList 类还有一个特殊的特性,就是如果链表中的一个组件被释放的话,它将被自动的从TComponentList 链表中删除。这是利用TComponent的FreeNotification方法可以在组件被销毁时通知链表,这样链表就可以将对象引用从链表中删除的。  

  TClassList 类

  Contnrs单元中还定义了TClassList类,类定义如下:

TClassList = class(TList)protected  function GetItems(Index: Integer): TClass;  procedure SetItems(Index: Integer; AClass: TClass);public  function Add(aClass: TClass): Integer;  function Remove(aClass: TClass): Integer;  function IndexOf(aClass: TClass): Integer;  procedure Insert(Index: Integer; aClass: TClass);  property Items[Index: Integer]: TClass   read GetItems write SetItems; default;end;

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  不同于前面两个类,这个类继承于TList的类只是将Add, Remove, IndexOf, Insert和Items 调用的参数从指针换成了TClass元类类型。

  TOrderedList, TStack和TQueue 类

  Contnrs单元还定义了其它三个类:TOrderedList, TStack和TQueue,类型定义如下:

TOrderedList = class(TObject)private FList: TList;protected  procedure PushItem(AItem: Pointer); virtual; abstract; ...public  function Count: Integer;  function AtLeast(ACount: Integer): Boolean;  procedure Push(AItem: Pointer);  function Pop: Pointer;  function Peek: Pointer;end;TStack = class(TOrderedList)protected  procedure PushItem(AItem: Pointer); override;end;TQueue = class(TOrderedList)protected  procedure PushItem(AItem: Pointer); override;end;

  要注意虽然TOrderedList 并不是从TList继承的,但是它在内部的实现时,使用了TList来储存指针。另外注意TOrderedList类的PushItem 过程是一个抽象过程,所以我们无法实例化 TOrderedList 类,而应该从TOrderedList继承新的类,并实现抽象的PushItem方法。TStack 和 TQueue 正是实现了PushItem抽象方法的类, 我们可以实例化TStack 和TQueue类作为后进先出的堆栈 (LIFO)和先进先出的队列(FIFO)。下面是这两个的的方法使用说明: 

             Count 返回列表中的项目数。

             AtLeast 可以用来检查链表的大小,判断当前列表中的指针数目是否大于传递的参数值,如果为True表示列表中的项目数大于传来的参数。 

             对于TStack类Push 方法将指针添加到链表的最后,对于TQueue类Push 方法则将指针插入到链表的开始。

             Pop返回链表的末端指针,并将其从链表中删除。 

             Peek返回链表的末端指针,但是不将其从链表中删除。 

  TObjectStack和TObjectQueue类

  Contnrs单元中最后两个类是TObjectStack和TObjectQueue类,类的定义如下:

TObjectStack = class(TStack)public  procedure Push(AObject: TObject);  function Pop: TObject;  function Peek: TObject;end;TObjectQueue = class(TQueue)public  procedure Push(AObject: TObject);  function Pop: TObject;  function Peek: TObject;end;

  这两个类只是TStack和TQueue 类的简单扩展,在链表中保存的是TObject的对象引用,而不是简单的指针。

  TIntList 类

  到目前为止,我们看到的容器类中保存的都是指针或者对象引用(对象引用其实也是一种指针)。

  那么我们能不能在链表中保存原生类型,如Integer,Boolean或者Double等呢。下面的我们定义的类TIntList 类就可以在链表中保存整数,这里我们利用了整数和指针都占用4个字节的存储空间,所以我们可以直接将指针映射为整数。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

unit IntList;interfaceuses Classes;type TIntList = class(TList)  protected   function GetItem(Index: Integer): Integer;   procedure SetItem(Index: Integer;    const Value: Integer);  public                  function Add(Item: Integer): Integer;   function Extract(Item: Integer): Integer;   function First: Integer;   function IndexOf(Item: Integer): Integer;   procedure Insert(Index, Item: Integer);   function Last: Integer;   function Remove(Item: Integer): Integer;   procedure Sort;   property Items[Index: Integer]: Integer    read GetItem write SetItem; default;  end;implementation{ TIntList }function TIntList.Add(Item: Integer): Integer;begin Result := inherited Add(Pointer(Item));end;function TIntList.Extract(Item: Integer): Integer;begin Result := Integer(inherited Extract(Pointer(Item)));end;function TIntList.First: Integer;begin Result := Integer(inherited First);end;function TIntList.GetItem(Index: Integer): Integer;begin Result := Integer(inherited Items[Index]);end;function TIntList.IndexOf(Item: Integer): Integer;begin Result := inherited IndexOf(Pointer(Item));end;procedure TIntList.Insert(Index, Item: Integer);begin  inherited Insert(Index, Pointer(Item));end;function TIntList.Last: Integer;begin Result := Integer(inherited Last);end;function TIntList.Remove(Item: Integer): Integer;begin Result := inherited Remove(Pointer(Item));end;procedure TIntList.SetItem(Index: Integer;  const Value: Integer);begin  inherited Items[Index] := Pointer(Value);end;function IntListCompare(Item1, Item2: Pointer): Integer;begin  if Integer(Item1)  Integer(Item2) then  Result := -1  else if Integer(Item1)  Integer(Item2) then  Result := 1  else  Result := 0;end;            procedure TIntList.Sort;begin  inherited Sort(IntListCompare);end;end.

  扩展TList,限制类型的对象列表 

Begin Listing Two - TMyObjectListTMyObject = class(TObject)public  procedure DoSomething;end;TMyObjectList = class(TObjectList)protected  function GetItems(Index: Integer): TMyObject;  procedure SetItems(Index: Integer; AMyObject: TMyObject);public  function Add(aMyObject: TMyObject): Integer;  procedure DoSomething;  function Remove(aMyObject: TMyObject): Integer;  function IndexOf(aMyObject: TMyObject): Integer;  procedure Insert(Index: Integer; aMyObject: TMyObject);  property Items[Index: Integer]: TMyObject   read GetItems write SetItems; default;end;...{ TMyObjectList }function TMyObjectList.Add(AMyObject: TMyObject): Integer;begin Result := inherited Add(AMyObject);end;procedure TMyObjectList.DoSomething;var i: Integer;begin  for i := 0 to Count-1 do  Items[i].DoSomething;end;function TMyObjectList.GetItems(Index: Integer): TMyObject;begin Result := TMyObject(inherited Items[Index]);end;function TMyObjectList.IndexOf(AMyObject: TMyObject): Integer;begin Result := inherited IndexOf(AMyObject);end;procedure TMyObjectList.Insert(Index: Integer; AMyObject: TMyObject);begin  inherited Insert(Index, AMyObject);end;function TMyObjectList.Remove(AMyObject: TMyObject): Integer;begin Result := inherited Remove(AMyObject);end;procedure TMyObjectList.SetItems(Index: Integer; AMyObject: TMyObject);begin  inherited Items[Index] := AMyObject;end;End Listing Two

  TStrings类

  出于效率的考虑,Delphi并没有象C++和Java那样将字符串定义为类,因此TList本身不能直接存储字符串,而字符串列表又是使用非常广泛的,为此Borland提供了TStrings类作为存储字符串的基类,应该说是它除了TList类之外另外一个最重要的Delphi容器类。

来源:http://www.tulaoshi.com/n/20160219/1607666.html

延伸阅读
//根据字符串,拆分字符串,相当于vb中的split函数 function SplitString(const Source,ch:string):TStringList; var   temp:String;   i:Integer; begin   Result:=TStringList.Create;   //如果是空自符串则返回空列表   if Source=''   then exit; &nbs...
标签: Delphi
  Delphi作为一种面向对象的可视化开发工具,以其开发程序的高速度和编译代码的高效率越来越受到广大编程人员的喜爱。尽管Delphi已经提供了非常强大的开发组件(VCL),但灵活使用API函数一定可以使你的程序增色不少。 状态键的检查 当今不少流行软件的编辑窗口(包括Delphi的代码编辑窗口)的底部都有一个状态条...
Delphi中的字符串 ——摘自网络 一:各种字符串  字符串是Object Pascal所有数据类型中最有用的类型。许多函数以字符串为传递参数。由于在Delphi中字符串的定义和使用有各种方式,包括Pascal中典型的字符串(String),Delphi支持的长字符串(ANSIString),类似于C语言的字符数组(Array of Char),指向字符的...
网上找来的 感觉对入门者很有启示 收藏一下了! No.1 判断逻辑类型 } var B: Boolean; begin B := Boolean(2); //这样只是为了调试//B := True; if B = True then ShowMessage('B = True'); //不建议//不安全 /////// if B then ShowMessage('B'); //建议//简短 end; var B: Boolean;...
1.DELPHI中操作ACCESS数据库(建立.mdb文件,压缩数据库)  以下代码在WIN2K,D6,MDAC2.6下测试通过,  编译好的程序在WIN98第二版无ACCESS环境下运行成功. //在之前uses ComObj,ActiveX //声明连接字符串 Const SConnectionString = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;' +'Jet OLEDB:Database Password=%s;'; //...

经验教程

441

收藏

9
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部