升虹小哥 發表於 2020-8-15 14:19:00

看看Delphi中的列表(List)和泛型

<p>前言</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最开始学习数据结构的时候,链表,堆栈,队列,数组,似乎只是一堆概念,随着使用中慢慢接触,其对应的模型,功能,一个个跃到眼前,变成了复杂模型数据处理中的最重要的部分。---By Murphy 20180424</p>
<p>1,列表</p>
<p>Delphi中的列表有很多,从数据结构上可以分作:TList(数据链),TQueue(队列),TStack(堆栈),TDictionary(字典表)等等; 而从功能上又可以分作TList(列表),TObjectList(对象列表),TComponentList(组件列表),TStringList(字串列表),TClassList(类列表)。</p>
<p>列表的数据结构性,决定了列表的基础方法,基本都是以增删改查,计数,排序为主;而功能列表中,进一步增强了对每个节点元素的检查和限制,从而增加了针对这种数据类型的更贴合的功能,例如:对象的自动销毁,或仅结构移除,构建排序比较规则等等。现在就让我们看几种具有代表性的列表</p>
<p>a,TList</p>
<p>我们首先来看看TList在DelphiRX10中的源码定义</p>
<p>&nbsp; TList = class(TObject)<br>&nbsp; private<br>&nbsp;&nbsp;&nbsp; FList: TPointerList;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; FCount: Integer;<br>&nbsp;&nbsp;&nbsp; FCapacity: Integer;<br>&nbsp; protected<br>&nbsp;&nbsp;&nbsp; function Get(Index: Integer): Pointer;<br>&nbsp;&nbsp;&nbsp; procedure Grow; virtual;<br>&nbsp;&nbsp;&nbsp; procedure Put(Index: Integer; Item: Pointer);<br>&nbsp;&nbsp;&nbsp; procedure Notify(Ptr: Pointer; Action: TListNotification); virtual;<br>&nbsp;&nbsp;&nbsp; procedure SetCapacity(NewCapacity: Integer);<br>&nbsp;&nbsp;&nbsp; procedure SetCount(NewCount: Integer);<br>&nbsp; public<br>&nbsp;&nbsp;&nbsp; type<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TDirection = System.Types.TDirection;</p>
<p>&nbsp;&nbsp;&nbsp; destructor Destroy; override;<br>&nbsp;&nbsp;&nbsp; function Add(Item: Pointer): Integer;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//添加一个新元素<br>&nbsp;&nbsp;&nbsp; procedure Clear; virtual;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //清空列表<br>&nbsp;&nbsp;&nbsp; procedure Delete(Index: Integer);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //删除对象元素并销毁<br>&nbsp;&nbsp;&nbsp; class procedure Error(const Msg: string; Data: NativeInt); overload; virtual;<br>&nbsp;&nbsp;&nbsp; class procedure Error(Msg: PResStringRec; Data: NativeInt); overload;<br>&nbsp;&nbsp;&nbsp; procedure Exchange(Index1, Index2: Integer);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //交换对象<br>&nbsp;&nbsp;&nbsp; function Expand: TList;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//扩展当前对象容量<br>&nbsp;&nbsp;&nbsp; function Extract(Item: Pointer): Pointer; inline;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //移除对象元素,而不是销毁,并且返回对象指针<br>&nbsp;&nbsp;&nbsp; function ExtractItem(Item: Pointer; Direction: TDirection): Pointer;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //从当前对象指针开始定向定位,查找到对应对象并移除&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; function First: Pointer; inline;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //当前对象指针移动到第一个元素<br>&nbsp;&nbsp;&nbsp; function GetEnumerator: TListEnumerator;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //一个抽象列表,没看懂这里的扩展性设计<br>&nbsp;&nbsp;&nbsp; function IndexOf(Item: Pointer): Integer;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //检索元素<br>&nbsp;&nbsp;&nbsp; function IndexOfItem(Item: Pointer; Direction: TDirection): Integer;<br>&nbsp;&nbsp;&nbsp; procedure Insert(Index: Integer; Item: Pointer);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //插入一个对象元素<br>&nbsp;&nbsp;&nbsp; function Last: Pointer;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //当前对象指针移动到最后一个元素上<br>&nbsp;&nbsp;&nbsp; procedure Move(CurIndex, NewIndex: Integer);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //将当前对象移动位置<br>&nbsp;&nbsp;&nbsp; function Remove(Item: Pointer): Integer; inline;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //移除对象<br>&nbsp;&nbsp;&nbsp; function RemoveItem(Item: Pointer; Direction: TDirection): Integer;<br>&nbsp;&nbsp;&nbsp; procedure Pack;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;//清空空对象</p>
<p>&nbsp;&nbsp; //TListSortCompare = function (Item1, Item2: Pointer): Integer;<br>&nbsp;&nbsp; //TListSortCompareFunc = reference to function (Item1, Item2: Pointer): Integer;<br>&nbsp;&nbsp;&nbsp; procedure Sort(Compare: TListSortCompare);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //排序函数,这里TListSortCompare对应的是排序函数的指针<br>&nbsp;&nbsp;&nbsp; procedure SortList(const Compare: TListSortCompareFunc);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //TListSortCompareFunc是对应TListSortCompare的匿名函数,方法定义更为灵活<br>&nbsp;&nbsp;&nbsp; procedure Assign(ListA: TList; AOperator: TListAssignOp = laCopy; ListB: TList = nil);&nbsp; //指定内容来源<br>&nbsp;&nbsp;&nbsp; property Capacity: Integer read FCapacity write SetCapacity;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; //空间计数<br>&nbsp;&nbsp;&nbsp; property Count: Integer read FCount write SetCount;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //元素计数<br>&nbsp;&nbsp;&nbsp; property Items: Pointer read Get write Put; default;<br>&nbsp;&nbsp;&nbsp; property List: TPointerList read FList;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //指针列表<br>&nbsp; end</p>
<p>我们可以看到,这个TList算所有列表之源,具备了所有列表类型的基础方法属性。</p>
<p>b, TObjectList</p>
<p>这种List的单元Contnrs需要额外引用一下,我们在这个类的源码中可以看到,几乎所有的方法名跟TList都是一致的,只不过元素对象参数由TPoint变成了TObject,另外,还增加了以下两个新的方法:</p>
<p>&nbsp;&nbsp;&nbsp; constructor Create(AOwnsObjects: Boolean); overload;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //重载了一个构造方法,这里可以在创建的时候直接指定其拥有者,如果是False,就跟TList差别很大了,相当于这个ObjectList是独立于元素存在的。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //这时候元素的空间需要额外的管理</p>
<p>&nbsp;&nbsp;&nbsp; property OwnsObjects: Boolean read FOwnsObjects write FOwnsObjects;&nbsp;&nbsp; //这个是ObjectList的一个属性,可以由构造方法带进来,也可以使用时改变。</p>
<p>c,TComponetList</p>
<p>这个是直接继承TObjectList的,同样的,所有元素由基础对象改成了组件。但是这个类中也增加了一个方法:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; procedure HandleFreeNotify(Sender: TObject; AComponent: TComponent);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //这个方法对应着procedure TComponent.FreeNotification(AComponent: TComponent);方法</p>
<p>这个方法使得其管理的对象释放更为灵活,释放一个元素组件的时候,不需要操作ComponentList ,可以直接操作元素,并通过元素组件的方法自动触发TComponentList来处理链结构。</p>
<p>&nbsp;</p>
<p>d,TStringList</p>
<p>TStringList跟TList并不是一脉相承的,而是继承TStrings的,而TStrings是继承TPersistent的,其方法完全是为字串服务的,跟TList有相似点,其变化又比TList系列更为复杂。因为其具备</p>
<p>一系列增加和管理对象的方法:</p>
<p>property Objects: TObject read GetObject write PutObject;</p>
<p>function AddObject(const S: string; AObject: TObject): Integer; virtual;</p>
<p>function IndexOfObject(AObject: TObject): Integer; virtual;</p>
<p>procedure InsertObject(Index: Integer; const S: string; AObject: TObject); virtual;</p>
<p>function ToObjectArray: TArray&lt;TObject&gt;;</p>
<p>除此之外,还具备字典配对的功能:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; property Names: string read GetName;</p>
<p>&nbsp;&nbsp;&nbsp; property KeyNames: string read GetKeyName;</p>
<p>&nbsp;&nbsp;&nbsp; property Values: string read GetValue write SetValue;<br>&nbsp;&nbsp;&nbsp; property ValueFromIndex: string read GetValueFromIndex write SetValueFromIndex;</p>
<p>这使得其功能和扩展性都显得极为强大,TStrings是个抽象类,而TStringList增加了Sort方法和对象耦合属性OwnsObjects。 当没有使用对象和字典配对的时候,TStringList看起来就象一个简单的字串数组。</p>
<p>e,TClassList</p>
<p>这个类似乎不需要额外谈的,类中类的列表形态,批量处理的情景除非是特别复杂的模型才可以用到。其继承类是TList,没有对象管理的拥有者功能。</p>
<p>&nbsp;</p>
<p>2,泛型</p>
<p>泛型的出现,直接弄得各种List似乎都变成了一种兼容的特例模式了。泛型的可以选择任何类型的数据元素,并可以以任何数据结构模式进行组合。虽然在数据定义阶段略显复杂,但是作为一种强力的数据扩展</p>
<p>可以应用的场景也多得多。</p>
<p>泛型的引用单元:Generics.Collections,泛型的定义模式:</p>
<p><img src="https://img2020.cnblogs.com/blog/1107379/202008/1107379-20200815141805554-928114615.png" alt="" loading="lazy"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div id="cnblogs_post_body" class="blogpost-body">
<p>a,泛型数据类型的构成基础</p>
<p>我们先来看看泛型单元中的前四个数据定义,他们是泛型构成的基础件:TArray(TObject),TEnumerator&lt;T&gt;(TObject),TEnumerable&lt;T&gt;(TObject),TListHelper(TObject)</p>
<p>&nbsp; TArray = class<br>&nbsp; private<br>&nbsp;&nbsp;&nbsp; class procedure QuickSort&lt;T&gt;(var Values: array of T; const Comparer: IComparer&lt;T&gt;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; L, R: Integer); static;<br>&nbsp;&nbsp;&nbsp; class procedure CheckArrays(Source, Destination: Pointer; SourceIndex, SourceLength, DestIndex, DestLength, Count: NativeInt); static;<br>&nbsp; public<br>&nbsp;&nbsp;&nbsp; class procedure Sort&lt;T&gt;(var Values: array of T); overload; static;<br>&nbsp;&nbsp;&nbsp; class procedure Sort&lt;T&gt;(var Values: array of T; const Comparer: IComparer&lt;T&gt;); overload; static;<br>&nbsp;&nbsp;&nbsp; class procedure Sort&lt;T&gt;(var Values: array of T;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const Comparer: IComparer&lt;T&gt;; Index, Count: Integer); overload; static;</p>
<p>&nbsp;&nbsp;&nbsp; class function BinarySearch&lt;T&gt;(const Values: array of T; const Item: T;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out FoundIndex: Integer; const Comparer: IComparer&lt;T&gt;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Index, Count: Integer): Boolean; overload; static;<br>&nbsp;&nbsp;&nbsp; class function BinarySearch&lt;T&gt;(const Values: array of T; const Item: T;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out FoundIndex: Integer; const Comparer: IComparer&lt;T&gt;): Boolean; overload; static;<br>&nbsp;&nbsp;&nbsp; class function BinarySearch&lt;T&gt;(const Values: array of T; const Item: T;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out FoundIndex: Integer): Boolean; overload; static; static;</p>
<p>&nbsp;&nbsp;&nbsp; class procedure Copy&lt;T&gt;(const Source: array of T; var Destination: array of T; SourceIndex, DestIndex, Count: NativeInt); overload; static;<br>&nbsp;&nbsp;&nbsp; class procedure Copy&lt;T&gt;(const Source: array of T; var Destination: array of T; Count: NativeInt); overload; static;<br>&nbsp; end;</p>
<p>这是额外为TArray定义的一段代码,本人看得不是特别懂,感觉这个主要的功能是为System中的TArray&lt;T&gt;定义作一个扩展。</p>
<p>注意,TArray&lt;T&gt;的定义是出现在System单元中:TArray&lt;T&gt; = array of T;</p>
<p>这个TArray扩展为后续的泛型定义,提供了一个本体。接下来,我们看看两个抽象类:TEnumerator&lt;T&gt;,TEnumerable&lt;T&gt;.</p>
<p>&nbsp; TEnumerator&lt;T&gt; = class abstract<br>&nbsp; protected<br>&nbsp;&nbsp;&nbsp; function DoGetCurrent: T; virtual; abstract;<br>&nbsp;&nbsp;&nbsp; function DoMoveNext: Boolean; virtual; abstract;<br>&nbsp; public<br>&nbsp;&nbsp;&nbsp; property Current: T read DoGetCurrent;<br>&nbsp;&nbsp;&nbsp; function MoveNext: Boolean;<br>&nbsp; end;</p>
<p>&nbsp;</p>
<p>&nbsp; TEnumerable&lt;T&gt; = class abstract<br>&nbsp; private<br>&nbsp; {$HINTS OFF}<br>&nbsp;&nbsp;&nbsp; function ToArrayImpl(Count: Integer): TArray&lt;T&gt;; // used by descendants<br>&nbsp; {$HINTS ON}<br>&nbsp; protected<br>&nbsp;&nbsp;&nbsp; function DoGetEnumerator: TEnumerator&lt;T&gt;; virtual; abstract;<br>&nbsp; public<br>&nbsp;&nbsp;&nbsp; destructor Destroy; override;<br>&nbsp;&nbsp;&nbsp; function GetEnumerator: TEnumerator&lt;T&gt;;<br>&nbsp;&nbsp;&nbsp; function ToArray: TArray&lt;T&gt;; virtual;<br>&nbsp; end;</p>
<p>这两个抽象类,TEnumerable是所有泛型的基类,定义出泛型的数据实体是TArray&lt;T&gt;模式,并且引用了另外一个抽象方法类TEnumerator ,使得泛型具备获取当前元素Current以及MoveNext导航功能。</p>
<p>这个设计很重要,我们可以看到Current和MoveNext在这里不再是数据结构的属性,而是作为元素基础功能出现的。</p>
<p>最后,我们再来看看一个附加的结构体:TListHelper = record ,它十分复杂,我没有太多时间去详细研究,暂时看到它是作为泛型的扩展属性使用的,所以就认为它是一个泛型的帮助信息扩展吧。</p>
<p>b,TList&lt;T&gt;</p>
<p>这个类型的篇幅还是比较长的,比TList要复杂多了,既融合了TList的基础定义,又加入了泛型的实现基础,下面我们一起看一看其定义的过程。</p>
<p>&nbsp; TList&lt;T&gt; = class(TEnumerable&lt;T&gt;)<br>&nbsp; private type<br>&nbsp;&nbsp;&nbsp; arrayofT = array of T;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;//定义了一个内部元数组类<br>&nbsp; var<br>&nbsp;&nbsp;&nbsp; FListHelper: TListHelper; // FListHelper must always be followed by FItems&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//暂且认为是帮助信息类,不做过多分析<br>&nbsp;&nbsp;&nbsp; FItems: arrayofT; // FItems must always be preceded by FListHelper&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//利用元数组类实现了一个元数据实体<br>&nbsp;&nbsp;&nbsp; FComparer: IComparer&lt;T&gt;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//为排序而诞生的比较方法指针<br>&nbsp;&nbsp;&nbsp; FOnNotify: TCollectionNotifyEvent&lt;T&gt;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//内部事件</p>
<p>&nbsp;&nbsp;&nbsp; function GetCapacity: Integer; inline;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到整个泛型的内存空间<br>&nbsp;&nbsp;&nbsp; procedure SetCapacity(Value: Integer); overload; inline;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //动态设置元素的Length<br>&nbsp;&nbsp;&nbsp; procedure SetCount(Value: Integer); inline;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //动态设置元素个数<br>&nbsp;&nbsp;&nbsp; function GetItem(Index: Integer): T; inline;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //根据序号获得指定元素<br>&nbsp;&nbsp;&nbsp; procedure SetItem(Index: Integer; const Value: T); inline;&nbsp;<br>&nbsp;&nbsp;&nbsp; procedure GrowCheck(ACount: Integer); inline;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Helper相关<br>&nbsp;&nbsp;&nbsp; procedure DoDelete(Index: Integer; Notification: TCollectionNotification); inline;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //根据序号删除并销毁某元素<br>&nbsp;&nbsp;&nbsp; procedure InternalNotify(const Item; Action: TCollectionNotification);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; function InternalCompare(const Left, Right): Integer;<br>&nbsp;&nbsp;&nbsp; property FCount: Integer read FListHelper.FCount write FListHelper.FCount;<br>&nbsp; protected<br>&nbsp;&nbsp;&nbsp; function ItemValue(const Item: T): NativeInt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //返回元素的值,NativeInt是内存中一种Int编码值。<br>&nbsp;&nbsp;&nbsp; function DoGetEnumerator: TEnumerator&lt;T&gt;; override;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //重新构建元素的导航功能。<br>&nbsp;&nbsp;&nbsp; procedure Notify(const Item: T; Action: TCollectionNotification); virtual;<br>&nbsp; public<br>&nbsp; type<br>&nbsp;&nbsp;&nbsp; TDirection = System.Types.TDirection;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//定义方向,用于List的定向操作<br>&nbsp;&nbsp;&nbsp; TEmptyFunc = reference to function (const L, R: T): Boolean;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//为空时的匿名函数<br>&nbsp;&nbsp;&nbsp; TListCompareFunc = reference to function (const L, R: T): Integer;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //为排序比较时的匿名函数</p>
<p>&nbsp;&nbsp;&nbsp;//再往下看基本就没什么新方法了,功能都是结合TList和TEnumerable的功能重组.</p>
<p>&nbsp;&nbsp; constructor Create; overload;<br>&nbsp;&nbsp;&nbsp; constructor Create(const AComparer: IComparer&lt;T&gt;); overload;<br>&nbsp;&nbsp;&nbsp; constructor Create(const Collection: TEnumerable&lt;T&gt;); overload;<br>&nbsp;&nbsp;&nbsp; destructor Destroy; override;</p>
<p>&nbsp;&nbsp;&nbsp; class procedure Error(const Msg: string; Data: NativeInt); overload; virtual;<br>{$IFNDEF NEXTGEN}<br>&nbsp;&nbsp;&nbsp; class procedure Error(Msg: PResStringRec; Data: NativeInt); overload;<br>{$ENDIF&nbsp; NEXTGEN}</p>
<p>&nbsp;&nbsp;&nbsp; function Add(const Value: T): Integer; inline;</p>
<p>&nbsp;&nbsp;&nbsp; procedure AddRange(const Values: array of T); overload;<br>&nbsp;&nbsp;&nbsp; procedure AddRange(const Collection: IEnumerable&lt;T&gt;); overload; inline;<br>&nbsp;&nbsp;&nbsp; procedure AddRange(const Collection: TEnumerable&lt;T&gt;); overload; inline;</p>
<p>&nbsp;&nbsp;&nbsp; procedure Insert(Index: Integer; const Value: T); inline;</p>
<p>&nbsp;&nbsp;&nbsp; procedure InsertRange(Index: Integer; const Values: array of T); overload;<br>&nbsp;&nbsp;&nbsp; procedure InsertRange(Index: Integer; const Collection: IEnumerable&lt;T&gt;); overload;<br>&nbsp;&nbsp;&nbsp; procedure InsertRange(Index: Integer; const Collection: TEnumerable&lt;T&gt;); overload;</p>
<p>&nbsp;&nbsp;&nbsp; procedure Pack; overload;<br>&nbsp;&nbsp;&nbsp; procedure Pack(const IsEmpty: TEmptyFunc); overload;</p>
<p>&nbsp;&nbsp;&nbsp; function Remove(const Value: T): Integer; inline;<br>&nbsp;&nbsp;&nbsp; function RemoveItem(const Value: T; Direction: TDirection): Integer; inline;<br>&nbsp;&nbsp;&nbsp; procedure Delete(Index: Integer); inline;<br>&nbsp;&nbsp;&nbsp; procedure DeleteRange(AIndex, ACount: Integer); inline;<br>&nbsp;&nbsp;&nbsp; function ExtractItem(const Value: T; Direction: TDirection): T; inline;<br>&nbsp;&nbsp;&nbsp; function Extract(const Value: T): T; inline;</p>
<p>&nbsp;&nbsp;&nbsp; procedure Exchange(Index1, Index2: Integer); inline;<br>&nbsp;&nbsp;&nbsp; procedure Move(CurIndex, NewIndex: Integer); inline;</p>
<p>&nbsp;&nbsp;&nbsp; function First: T; inline;<br>&nbsp;&nbsp;&nbsp; function Last: T; inline;</p>
<p>&nbsp;&nbsp;&nbsp; procedure Clear; inline;</p>
<p>&nbsp;&nbsp;&nbsp; function Expand: TList&lt;T&gt;; inline;</p>
<p>&nbsp;&nbsp;&nbsp; function Contains(const Value: T): Boolean; inline;<br>&nbsp;&nbsp;&nbsp; function IndexOf(const Value: T): Integer; inline;<br>&nbsp;&nbsp;&nbsp; function IndexOfItem(const Value: T; Direction: TDirection): Integer; inline;<br>&nbsp;&nbsp;&nbsp; function LastIndexOf(const Value: T): Integer; inline;</p>
<p>&nbsp;&nbsp;&nbsp; procedure Reverse; inline;</p>
<p>&nbsp;&nbsp;&nbsp; procedure Sort; overload;<br>&nbsp;&nbsp;&nbsp; procedure Sort(const AComparer: IComparer&lt;T&gt;); overload;<br>&nbsp;&nbsp;&nbsp; function BinarySearch(const Item: T; out Index: Integer): Boolean; overload;<br>&nbsp;&nbsp;&nbsp; function BinarySearch(const Item: T; out Index: Integer; const AComparer: IComparer&lt;T&gt;): Boolean; overload;</p>
<p>&nbsp;&nbsp;&nbsp; procedure TrimExcess; inline;</p>
<p>&nbsp;&nbsp;&nbsp; function ToArray: TArray&lt;T&gt;; override; final;</p>
<p>&nbsp;&nbsp;&nbsp; property Capacity: Integer read GetCapacity write SetCapacity;<br>&nbsp;&nbsp;&nbsp; property Count: Integer read FListHelper.FCount write SetCount;<br>&nbsp;&nbsp;&nbsp; property Items: T read GetItem write SetItem; default;<br>&nbsp;&nbsp;&nbsp; property List: arrayofT read FItems;</p>
<p>&nbsp;&nbsp;&nbsp; property OnNotify: TCollectionNotifyEvent&lt;T&gt; read FOnNotify write FOnNotify;</p>
<p>&nbsp;&nbsp;&nbsp; type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //这里重新指定了元素导航的功能实现<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TEnumerator = class(TEnumerator&lt;T&gt;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FList: TList&lt;T&gt;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FIndex: Integer;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function GetCurrent: T;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function DoGetCurrent: T; override;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function DoMoveNext: Boolean; override;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; constructor Create(const AList: TList&lt;T&gt;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; property Current: T read GetCurrent;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function MoveNext: Boolean;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end;</p>
<p>&nbsp;&nbsp;&nbsp; function GetEnumerator: TEnumerator; reintroduce; inline;<br>&nbsp; end;</p>
<p>该类应该是泛型中使用最为广泛的一个类,我们既可以用以后的类来组合使用,又可以重新定义其各项基础功能实现扩展。</p>
<p>直接使用的模式:&nbsp;DataSetList: TList&lt;TDataSet&gt;;</p>
<p>重新定义的模式:</p>
<p>type</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TSpecList&lt;T&gt;=class(TList&lt;T&gt;)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; ....</p>
<p>end;</p>
<p>使用的时候直接将&lt;T&gt;实化:DataSetList: TSpecList&lt;TDataSet&gt;;</p>
<p>c,其他几种使用频率比较高的泛型:</p>
<p>TQueue&lt;T&gt; = class(TEnumerable&lt;T&gt;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //队列泛型,定义几乎跟TList&lt;T&gt; 一样,所以这里的方法说明省去。</p>
<p>TThreadList&lt;T&gt; = class&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //线程泛型,实体是TList&lt;T&gt;,针对其控制增加了锁定方法。</p>
<p>TStack&lt;T&gt; = class(TEnumerable&lt;T&gt;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //堆栈泛型,增加了Pop和Push方法,其他定义几乎跟TList&lt;T&gt;一致。</p>
<p>&nbsp; TPair&lt;TKey,TValue&gt; = record<br>&nbsp;&nbsp;&nbsp; Key: TKey;<br>&nbsp;&nbsp;&nbsp; Value: TValue;<br>&nbsp;&nbsp;&nbsp; constructor Create(const AKey: TKey; const AValue: TValue);<br>&nbsp; end;<br>&nbsp; TDictionary&lt;TKey,TValue&gt; = class(TEnumerable&lt;TPair&lt;TKey,TValue&gt;&gt;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //字典泛型,这个比较有用,数据是以Key和Value成对出现。主要是增加了Hash方法,各种元素操作也都以Key作为参数。</p>
<p>这些泛型都是基于数据结构的变化。</p>
<p>&nbsp;</p>
<p>d,与对象相关的泛型扩展 TObjectList&lt;T&gt;,</p>
<p>TObjectList&lt;T: class&gt; = class(TList&lt;T&gt;)&nbsp;&nbsp;&nbsp;</p>
<p>&nbsp; private<br>&nbsp;&nbsp;&nbsp; FOwnsObjects: Boolean;<br>&nbsp; protected<br>&nbsp;&nbsp;&nbsp; procedure Notify(const Value: T; Action: TCollectionNotification); override;<br>&nbsp; public<br>&nbsp;&nbsp;&nbsp; constructor Create(AOwnsObjects: Boolean = True); overload;<br>&nbsp;&nbsp;&nbsp; constructor Create(const AComparer: IComparer&lt;T&gt;; AOwnsObjects: Boolean = True); overload;<br>&nbsp;&nbsp;&nbsp; constructor Create(const Collection: TEnumerable&lt;T&gt;; AOwnsObjects: Boolean = True); overload;<br>&nbsp;&nbsp;&nbsp; destructor Destroy; override;<br>&nbsp;&nbsp;&nbsp; property OwnsObjects: Boolean read FOwnsObjects write FOwnsObjects;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//主要就是增加了这个属性,让其元素耦合性降低<br>&nbsp; end;</p>
<p>TObjectQueue&lt;T: class&gt; = class(TQueue&lt;T&gt;)</p>
<p>TObjectStack&lt;T: class&gt; = class(TStack&lt;T&gt;)</p>
<p>TObjectDictionary&lt;TKey,TValue&gt; = class(TDictionary&lt;TKey,TValue&gt;)</p>
<p>以上这四种泛型都是在原有泛型上的轻微扩展,同列表的对象扩展一样。最主要的属性就是OwnsObjects,使得整个泛型数据集,可以拥有对象空间的独立管理能力。</p>
<p>&nbsp;</p>
<p>3,小结</p>
<p>为什么我们要使用泛型?泛型数据的优势和劣势又各是什么呢?</p>
<p>其实Delphi引用泛型数据算比较落后的了,Java很早就有泛型概念,而FrameWork也是从2.0&nbsp;开始就引入了泛型数据,而Delphi是从Delphi2009~Delphi2010才正式引入泛型。</p>
<p>泛型的早期模式,其实就是各种列表,也就是本篇的第1点所阐述的内容,对比泛型和列表,其实泛型能实现的方式列表都可以实现,而列表的异构元素结构,泛型是不适合的。</p>
<p>那么泛型相对列表有什么优势呢?优势主要体现在两个方面:重用性,安全高效性。</p>
<p>a,重用性</p>
<p>这里举个例子说明,我们如果需要两个列表TStringxxxList,TIntxxxList,如果用列表继承的概念,那就必须要写两个定义:</p>
<p>type TStringList=class(TList)</p>
<p>...这可能会有count方法</p>
<p>end;</p>
<p>type TIntxxxList=class(TList)</p>
<p>...这可能会有count方法</p>
<p>end;</p>
<p>&nbsp;如果换作泛型,就只需要定义一次就好了,列表中通性的方法是固定的。</p>
<p>type TxxxList&lt;T&gt;=class(TList&lt;T&gt;)</p>
<p>...这里可能有count方法</p>
<p>end;</p>
<p>使用时,我们用TxxxList&lt;string&gt;,TxxxList&lt;Int&gt;就可以取代两种List。</p>
<p>b,安全高效性</p>
<p>虽然用列表也可以实现子类型的存取,但是在使用过程中就免不了要进行类型转换和判断(装箱和拆箱),即不安全,也会影响到系统效率。</p>
<p>例如:</p>
<p>&nbsp; AllDataSets : TComponentList;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //用List进行一个数据集的存储。</p>
<p>&nbsp; AllDataSets := TComponentList.Create(False);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //非耦合性列表<br>&nbsp; AllDataSets.Add(ADataSet);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; //存放一个数据集</p>
<p>到这一步似乎跟泛型都没什么差异,然而取的时候就比较麻烦了。</p>
<p>if AllDataSets.Items is TDataSet then</p>
<p>&nbsp;funxxx(AllDataSets.Items as TDataSet);</p>
<p>这不仅仅意味着要承受各种非规则数据的干扰,还必须进行强制类型转换,才能完成其初期设计的【数据集列表】这样的概念。反观泛型就要简单得多:</p>
<p>定义:AllDataSets : TObjectList&lt;TDataSet&gt;;</p>
<p>AllDataSets := TObjectList&lt;TDataSet&gt;.Create(False);</p>
<p>AllDataSets.Add(ADataSet);&nbsp;</p>
<p>我们在使用中,完全不担心类型问题,直接调用就好了,而且即便真的有类型匹配的错误,在编译期就可以将其呈现出来。</p>

</div>
<div id="MySignature">不求功能强大,但求小巧融洽</div>

</div>
<div id="MySignature" role="contentinfo">
    好的代码像粥一样,都是用时间熬出来的<br><br>
来源:https://www.cnblogs.com/jijm123/p/13508613.html
頁: [1]
查看完整版本: 看看Delphi中的列表(List)和泛型