Containers in Delphi (1)

Source: Internet
Author: User

A new contnrs unit has been added to VCL since Delphi 5, and eight new classes have been defined in the unit, all of which are based on Standard .

Tlist class

The tlist class is actually a container class that can store pointers and provides a series Method And attribute to add, delete, rearrange, locate, access and sort the classes in the container. It is a container Based on the array mechanism, similar to the vector in C ++ and the arraylist in Java, tlist is often used to save a group of object lists. The array-based implementation mechanism makes it very fast to access objects in the container by subscript, however, as the number of objects in the container increases, the insert and delete object speeds down. Therefore, it is not suitable for scenarios where objects are frequently added or deleted. The following describes the attributes and methods of the tlist class:

Attribute Description
Count: Integer; Number of items in the returned list
Items [Index: Integer]: Pointer; default Directly access Project
Method Type Description
Add (Item: Pointer): Integer; Function Used to add pointers to the list.
Clear; Process Clear items in the list
Delete (Index: Integer ); Process Delete the corresponding index items in the list
IndexOf (Item: Pointer): Integer; Function Returns the index of the pointer in the list.
Insert (Index: Integer; Item: Pointer ); Process Insert a project to a specified position in the list
Remove (Item: Pointer): Integer; Function Delete pointer from List
Name Type Description
Capacity: Integer; Property It can be used to obtain or set the number of pointers that the list can accommodate.
Extract (Item: Pointer): Pointer; Function Extract is similar to Remove, which can delete pointers from the list. The difference is that the pointer to be deleted is returned.
Exchange (Index1, Index2: Integer ); Procedure Two pointers in the exchange list
First: Pointer; Function Returns the first pointer in the linked list.
Last: Pointer; Function Returns the last pointer in the linked list.
Move (CurIndex NewIndex: Integer ); Procedure Move pointer from current position to new position
Pack; Procedure Delete all nil pointers from the list
Sort (Compare: TListSortCompare ); Procedure Used to sort items in the linked list. You can set the Compare parameter to a customized sorting function.

Tobjectlist class

The tobjectlist class inherits directly from the tlist class and can be used as the object container. The tobjectlist class is defined as follows:

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;

Unlike the tlist class, methods like add, remove, indexof, and insert of the tobjectlist class all need to pass the tobject object as a parameter. Due to the strong type check during the compilation period, this makes tobjectlist more suitable for saving objects than tlist. In addition, the tobjectlist object has the ownsobjects attribute. If it is set to true (default value), different from the tlist class, the tobjectlist object will destroy any objects deleted from the list. Whether you call the delete, remove, clear method or release the tobjectlist object, all objects in the list will be destroyed. With the tobjectlist class, we no longer need to use loops to release objects. This avoids Memory leakage caused by forgetting to release objects in the linked list when releasing Linked List objects. In addition, it should be noted that the ownsobjects attribute does not affect the extract method. The extract method of tobjectlist is similar to tlist, but only removes the object reference from the list without destroying the object.

The tobjectlist object also provides a findinstanceof function, which can return the index of an object instance of the specified object type in the list. If the aexact parameter is true, only the instance of the specified object type will be located. If the aexact object is false, the Aclass subclass instance will also be located. The astartat parameter can be used to locate multiple instances in the list. When you call the findinstanceof function every time, you can add 1 to the starting index and locate the next object until findinstanceof returns-1. The following code is used:

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

Tcomponentlist class

The tcomponentlist class is also defined in the contnrs unit. The class definition is as follows:

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;

Note that tcomponentlist is inherited from the tobjectlist class, and its add, remove, indexof, insert, and items method calls both use tcomponent parameters instead of the tobject type, therefore, it is suitable for containers used as tcomponent objects. The tcomponentlist class also has a special feature, that is, if a component in the linked list is released, it will be automatically deleted from the tcomponentlist linked list. The freenotification method of tcomponent can be used to notify the linked list when the component is destroyed, so that the linked list can delete the object reference from the linked list.

Tclasslist class

The tclasslist class is also defined in the contnrs unit. The class is defined as follows:

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;

Unlike the first two classes, the classes inherited from tlist only change the parameters called by add, remove, indexof, insert, and items from the pointer to the tclass metadata type.

Torderedlist, tstack, and tqueue

The contnrs Unit also defines three other classes: torderedlist, tstack, and tqueue. The types are defined as follows:

TOrderedList = class(TObject)
*******
 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;

Although TOrderedList is not inherited from TList, it uses TList to store pointers during internal implementation. Note that the PushItem process of the TOrderedList class is an abstract process, so we cannot instantiate the TOrderedList class. Instead, we should inherit the new class from TOrderedList and implement the abstract PushItem method. TStack and TQueue are classes that implement PushItem abstract methods. We can instantiate TStack and TQueue classes as the following first-in-first-out stacks (LIFO) and first-in-first-out queues (FIFO ). The following describes how to use these two methods:

· Count: returns the number of items in the list.

· AtLeast can be used to check the linked list size and determine whether the number of pointers in the current list is greater than the passed parameter value. If it is True, it indicates that the number of items in the list is greater than the passed parameter.

· For the TStack Push method, add the pointer to the end of the linked list. For the TQueue Push method, insert the pointer to the beginning of the linked list.

· Pop returns the end pointer of the linked list and deletes it from the linked list.

· Peek returns the end pointer of the linked list, but does not delete it from the linked list.

TObjectStack and TObjectQueue class

The last two classes in Contnrs are TObjectStack and TObjectQueue. The class is defined as follows:

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;

TIntList class

These two classes are only simple for the TStack and TQueue classes. Extension The object reference of TObject is saved in the linked list, rather than a simple pointer.

 

So far, we have seen that the container class stores pointer or object reference (Object Reference is actually a pointer ).

So can we store native types such as Integer, Boolean, or Double in the linked list. The TIntList class we define below can save integers in the linked list. Here we use the four bytes of storage space occupied by both integers and pointers, so we can map the pointer to an integer directly.

unit IntList;
interface
uses
 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.

Extended TList, restriction type Object List

Begin Listing Two - TMyObjectList
TMyObject = 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

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.