Delphi容器类之---TList、TObjectList、TComponentList、TClassList的使用

转载自:http://blog.csdn.net/iseekcode/article/details/4922001


从Delphi5开始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;  函数。返回指针在列表中的索引。
  • Remove(Item: Pointer): integer;  函数。从列表中删除指针。
  • Capacity: Integer。  属性。可以用来获取或设定列表可以容纳的指针的数目。
  • Extract(Item: Pointer): Pointer;  函数。Extract类似于Remove可以将指针从列表中删除,不同的是返回被删除的指针。
  • Exchange(Index1, Index2: Integer);  过程。交换列表中的两个指针。
  • First: Pointer;  函数。返回链表中的第一个指针。
  • Last: Pointer;  函数。返回链表中的最后一个指针。
  • Move(CurIndex, NewIndex: Integer);  过程。将指针从当前位置移动到新的位置。
  • Pack;  过程。从列表中删除所有nil的指针。
  • Sort(Compare: TListSortCompare);  过程。用来对链表中的项目进行排序,可以设定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对象将销毁任何从列表中删除的对象。

  有了TObjectList类,我们就再也不用使用循环来释放对象了。这就避免了释放链表对象时,由于忘记释放链表中的对象而导致的内存泄漏。

  另外需要注意的是OwnsObjects属性不会影响到Extract方法,TObjectList的Extract方法行为类似于TList,知识从列表中移除对象引用,而不会销毁对象。

  

  TObjectList对象还提供了一个FindInstanceOf 函数,可以返回只有指定对象类型的对象在列表中的索引。如果AExtract参数为True,只有指定对象类型的对象实例会被定位,如果AExtract对象为False,AClass的子类实例也将被定为。AStartAt参数可以用来找到列表中的多个实例,只要每次调用FindInstanceOf函数时,将起始索引加1,就可以定位到下一个对象,之道FindInstanceOf 返回-1。下面是示例代码:

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

   

TComponentList                 

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

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;

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


TOrderedList, TStack和TQueue 类

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

 TOrderedlist类                   

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类                   

TStack = class(TOrderedList)

protected

   procedure PushItem(AItem: Pointer); override;

end;

TQueue类                   

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的对象引用,而不是简单的指针。

 



  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值