Tlist
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的更多相关文章
- Tlist删除技巧
二. 从TList开始分析-- 为了写一个更好的性能ISAPI Filter,我需要更快速地从TList中删除部分连续的Item.比如这样的一段代码: var p : pChar = 'abcd ...
- Delphi容器类之---Tlist,TStringlist,THashedStringlist的效率比较
转载自:http://www.ylzx8.cn/windows/delphi/73200.html 本人在做一个测试,服务器是IOCP的,我假定最大链接数是50000个. 测试背景:如果每个链接之间的 ...
- Delphi容器类之---TList、TObjectList、TComponentList、TClassList
转载自:http://blog.csdn.net/iseekcode/article/details/4922001 从Delphi5开始VCL中增加了新的Contnrs单元,单元中定义了8个新的类, ...
- Delphi容器类之---TList、TStringList、TObjectList,以及一个例程的代码分析
转载自:http://blog.csdn.net/jqandjq/article/details/5429137 看了这里标题,大家可能以为我会谈TListBox控件,那就错了.我要谈的是Delphi ...
- 关于 Record & TList 的一点吐槽
需求是把record 保存在TList中,并可以随时改变TList中Items的各项值. 代码很简单: MyRec = record MyStr: string; constructor Create ...
- Delphi 2009 泛型容器单元(Generics.Collections)[1]: TList<T>
Delphi 2009 新增了泛型容器单元: Generics.Collections, 同时还有一个 Generics.Defaults 单元做支持. Generics.Collections 包含 ...
- 一个继承TList的例子
类声明部分: TDMSTrains = class(TList) private FHashed: Boolean; FHashList: TFpHashList; FOwnsObjects: Boo ...
- delphi下TList的用法
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- TList,TObjectList 使用——资源释放
TOjectList = Class (Tlist); TOjectList继承Tlist,从名字上看就可以知道它是专门为对象列表制作的,那么他到底丰富了那些功能呢? 首先是 TObject 作为对象 ...
随机推荐
- 如何使用NPOI 导出到excel和导入excel到数据库
近期一直在做如何将数据库的数据导出到excel和导入excel到数据库. 首先进入官网进行下载NPOI插件(http://npoi.codeplex.com/). 我用的NPOI1.2.5稳定版. 使 ...
- Android——数据库相关(课堂整理)
layout文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...
- python built-in delattr()
delattr(object,name) 使用此函数必须保证name是可以被删除,即先调用setattr(object,name,value) name必须是字符串并且是object的属性. 函数的作 ...
- VISIBLE、INVISIBLE、GONE的区别
VISIBLE:设置控件可见 INVISIBLE:设置控件不可见 GONE:设置控件隐藏 而INVISIBLE和GONE的主要区别是:当控件visibility属性为INVISIBLE时,界面保留了v ...
- redis 集群环境搭建-redis集群管理
集群架构 (1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽. (2)节点的fail是通过集群中超过半数的节点检测失效时才生效. (3)客户端与redi ...
- 移动POS机
1.怎么识别手刷机所属公司是否是二清公司,甚至是多清 去银行,手机银行,网上银行查询该笔款是哪里汇出的,如果是银行或合法支付公司汇出,一般为一清机,如果是个人或无支付牌照的支付公司,一般为二清机: 已 ...
- mysql特殊处理
mysql> create table ef (bc time);Query OK, 0 rows affected (0.03 sec) mysql> insert into ef va ...
- PDO多种方式取得查询结果
PDO多种方式取得查询结果 01 December 2009 1:26 Tuesday by Sjolzy PDO最大的特点之一是它的灵活性,本节将介绍如何取得查询结果,包括: 数组(数值或关联数组) ...
- 黄聪:MYSQL使服务器内存CPU占用过高问题的分析及解决方法
方法一: 使用 show processlist 语句,查找负荷最重的 SQL 语句,优化该SQL,比如适当建立某字段的索引. 方法二: #查看慢SQL日志是否启用mysql> show var ...
- Cordova从服务器更新客户端的JS文件
思路: 1.主要使用 Cordova的File插件 2.获取需要替换的js文件安装后的路径 3.软件使用js发起ajax请求,后台返回版本号跟客户端版本号对比 4.如果发现需要更新js文件,则用js调 ...