Tlist (Classes.pas)

在我刚开始接触TList的时候,TList搞得我迷雾重重,都是Capacity属性惹的祸。我查了Delphi的帮助,它说Capacity是TList的最大容量,又在什么地方说

MaxInt div 4是TList的最大容量。最后我搞明白了,Capacity是临时的,MaxInt div 4才是真正的最大容量。只要你的内存受得了就行,算起来一共是4G。

在TList 内部有一个FList指针指向一个Pointer数组,Capacity就是这个数组的大小。奇怪的是Capacity是可写的。我当时就在想,如果一直使用Add 直到超出了

Capacity的范围,会怎么样呢?为了解决这个问题,我特地打开了TList 的代码,结果发现如下几行(注释是我自己加的):

function TList.Add(Item: Pointer): Integer;

begin

Result := FCount; { 返回Item 所在的位置}

{ 如果FList 数祖被填满了装不下新的Item,那么TList 自动增加Capacity(也就是自动增加FList 指向的数组的大小)}

if Result = FCapacity then

Grow;

{ 扩大了FList 的大小后,就能把Item放进数组了}

FList^[Result] := Item;

Inc(FCount);

if Item <> nil then

Notify(Item, lnAdded);

{给TList 一个信号,通知TList 已经加上了一个新的Item }

end;

procedure TList.Grow;

var

Delta: Integer;

begin

{增加的规则是,如果数量小于或等于8,那么增加4 ;如果数量在8 之上,小于或等于64 ,那么增加16 ;如果数量比64还大,那么一次增加大约1/4 的空间}

if FCapacity > 64 then

Delta := FCapacity div 4

else

if FCapacity > 8 then

Delta := 16

else

Delta := 4; { 改变数组大小}

SetCapacity(FCapacity + Delta);

end;

既然Capacity会自动增加,那么还要Capacity干什么呢?还不如使用链表。不过我后来意识到,在使用链表的时候,取得某个位置的指针比数组困难,

要用比较费时间的循环。TList刚好解决了这个问题。我们既可以把TList 当成数组,也可以把它当成链表。

TList 除了保存的对象是指针以外,其它地方都与TstringList很像。所以接下来我只介绍二者不同之处。

我们同样可以使用TList或者TList.Items获得某一位置的指针如果嫌TList.Items是属性没有效率的话,这里还有一个List属性,指向内部的FList,可以这么用:

TList.List^。

TList提供了First和Last两个属性,分别返回第一个和最后一个指针。

TList 也提供了一个Remove方法。与Delete不同的是,Delete删除的是已知位置的指针,

Remove删除的是已知指针。只要TList 包含有你想删除的指针,就可以使用Remove(Pointer)。

Remove的返回值是指针在还没有被删除之前的位置。使用方法如下:

procedure Delete(Index: Integer);

function Remove(Item: Pointer): Integer;

TList还有一个Pack方法。它能够把所有不是nil的指针聚在一起,同时把Count 的值改变,

这样,所有没用的指针就会被删除,但是并不会减少Capacity。如果你想把没用的空间都释放掉的话,可以把Capacity

设置成Count。

最后,我想说的是Protected里的Notify。大家在Add的代码里就能看到,在Insert、Delete之类的代码里我们也能看得到Notify的踪迹。既然FList

的内容已经被改变了,Notify 还要做什么工作呢?看一下Notify的代码:学习笔记

TListNotification = (lnAdded, lnExtracted, lnDeleted);

procedure TList.Notify(Ptr: Pointer; Action: TListNotification);

begin

end;

留着一个空的Notify

有什么用呢?再看它的声明:

procedure Notify(Ptr: Pointer; Action: TListNotification);

virtual;

原来Notify 是一个虚函数,当我们因为有特殊要求而继承TList类的话,只要TList

的内容一改变,我们就能得到通知。不过前提是我们要覆盖N o t i f y 这个Procedure。

Tlist的更多相关文章

  1. Tlist删除技巧

    二.    从TList开始分析-- 为了写一个更好的性能ISAPI Filter,我需要更快速地从TList中删除部分连续的Item.比如这样的一段代码: var p : pChar = 'abcd ...

  2. Delphi容器类之---Tlist,TStringlist,THashedStringlist的效率比较

    转载自:http://www.ylzx8.cn/windows/delphi/73200.html 本人在做一个测试,服务器是IOCP的,我假定最大链接数是50000个. 测试背景:如果每个链接之间的 ...

  3. Delphi容器类之---TList、TObjectList、TComponentList、TClassList

    转载自:http://blog.csdn.net/iseekcode/article/details/4922001 从Delphi5开始VCL中增加了新的Contnrs单元,单元中定义了8个新的类, ...

  4. Delphi容器类之---TList、TStringList、TObjectList,以及一个例程的代码分析

    转载自:http://blog.csdn.net/jqandjq/article/details/5429137 看了这里标题,大家可能以为我会谈TListBox控件,那就错了.我要谈的是Delphi ...

  5. 关于 Record & TList 的一点吐槽

    需求是把record 保存在TList中,并可以随时改变TList中Items的各项值. 代码很简单: MyRec = record MyStr: string; constructor Create ...

  6. Delphi 2009 泛型容器单元(Generics.Collections)[1]: TList<T>

    Delphi 2009 新增了泛型容器单元: Generics.Collections, 同时还有一个 Generics.Defaults 单元做支持. Generics.Collections 包含 ...

  7. 一个继承TList的例子

    类声明部分: TDMSTrains = class(TList) private FHashed: Boolean; FHashList: TFpHashList; FOwnsObjects: Boo ...

  8. delphi下TList的用法

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  9. TList,TObjectList 使用——资源释放

    TOjectList = Class (Tlist); TOjectList继承Tlist,从名字上看就可以知道它是专门为对象列表制作的,那么他到底丰富了那些功能呢? 首先是 TObject 作为对象 ...

随机推荐

  1. 在Swift中应用Grand Central Dispatch(上)转载自的goldenfiredo001的博客

    尽管Grand Central Dispatch(GCD)已经存在一段时间了,但并非每个人都知道怎么使用它.这是情有可原的,因为并发很棘手,而且GCD本身基于C的API在 Swift世界中很刺眼. 在 ...

  2. linux php redis扩展的安装和redis服务的安装

    一.php redis扩展的安装 wget http://pecl.php.net/get/redis-2.2.7.tgztar zvxf redis-2.2.7.tgzcd redis-2.2.7/ ...

  3. 【转载】基于ANSYS APDL的有裂纹平板问题的断裂力学仿真(PLANE183)

    原文地址:http://blog.sina.com.cn/s/blog_9e19c10b0102vnw7.html 对于一般的强度问题,我们总是用应力来度量其强度的.但是对于有裂纹的,高强度的构件,使 ...

  4. JAVA生成TXT日志文件

    /** * 生成日志文件(文件的位置在Tomcat的安装路径下) * @param str */ public static void LogForTXT(String str) { try { St ...

  5. kuangbin_MST C (POJ 2031)

    全程double精度就能过了 间接0距离不用管 prim自动连起来的 G++交的话只能用%f输出 C++的话加不加l都可以 (这么说以后用%f肯定不会错咯) 不过我不懂为什么他们的空间时间差了好多倍. ...

  6. Nginx-ngx_lua模块原理和内置函数

    ngx_lua模块的原理: 1.每个worker(工作进程)创建一个Lua VM,worker内所有协程共享VM:2.将Nginx I/O原语封装后注入 Lua VM,允许Lua代码直接访问:3.每个 ...

  7. F1 分数

    F1 分数会同时考虑精确率和召回率,以便计算新的分数. 可将 F1 分数理解为精确率和召回率的加权平均值,其中 F1 分数的最佳值为 1.最差值为 0: F1 = 2 * (精确率 * 召回率) / ...

  8. PHP判断访问终端,电脑或手机访问

    函数代码: //判断电脑或手机访问 function is_mobile(){ $user_agent = $_SERVER['HTTP_USER_AGENT']; $mobile_agents = ...

  9. JSON库之性能比较:JSON.simple VS GSON VS Jackson VS JSONP

    从http://www.open-open.com/lib/view/open1434377191317.html 转载 Java中哪个JSON库的解析速度是最快的? JSON已经成为当前服务器与WE ...

  10. centos之Haproxy 负载均衡学习笔记

    HAProxy的特点是:1.支持两种代理模式:TCP(四层)和HTTP(七层),支持虚拟主机:2.能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作3.支持url检测后端的 ...