For specialised collections, you have builtIn objects (like TStringList). But for more control i advise you to use the TList object (from where all the specialised collections are derived).
The main advantage is that TList stores pointers to objects and therefore you can insert as many objects of different types that you want. It allows you to add, delete, count objects.
For example let's say you create a class called MyObj
Code:
type MyObj = class
attribute1 : integer;
attribute2 : string;
procedure proc1();
function func1() : integer;
end;
every object you create automatically inherits delphi's TObject object. this includes freeing memory after use, storing class name and so on...
now you can either create collection a class that extends the TList object or you can directly use TList. let's take the first case (because by deriving TList you get to add attributes, functions and procedures that you need in addition to those of TList):
Code:
type MyObjCollection = class (TList)
collectionAttr1 : integer;
collectionAttr2 : string;
...so on...
constructor Create();
function AddObj(obj : MyObj) : boolean;
function getObjWithAttr2(value : string) : TList;
end;
TList has builtIn procedures for adding, inserting, deleting, counting element. but if you need to apply modifications to the objects you include, you could create a procedure that first does all this then calls TList's add method.
The second function (getObjWithAttr2(value : string) : TList

could be used to return a list only with the objects that have attribute2 equal to the value parameter.(just an example).
Now let's take a look at the implementation part:
Code:
implementation
constructor MyObjCollection.Create();
begin
// set the default values of the collection
self.collectionAttr1 := 0;
self.collectionAttr2 := '';
end;
function MyObjCollection.AddObj(obj : MyObj) : boolean;
var
ok : boolean;
begin
result := false;
ok := false;
//do checking procedure (let's say you need the obj to satisfy certain conditions before adding it to the collection). if it meets the conditions then ok := true;
if ok then
begin
self.add(obj);
result := true;
end;
end;
function MyObjCollection.getObjWithAttr2(value : string) : TList;
var
resList : TList;
i : integer;
begin
// we create a new TList to contain the objects we have to return
resList := TList.Create();
resList.Clear;
for i:=0 to self.Count-1 do
begin
//now we call the object stored at position i in the list. notice that you need to make a casting since the list only contains pointer addresses of the objects stored within
if MyObj(self.Items[i]).attribute2 = value then resList.Add(MyObj(self.Items[i]));
end;
result := resList;
end;
now that you defined the two classes you can start working with them. in a function you could write:
Code:
procedure startUsingClasses();
var
objCollection : MyObjCollection;
tempObj : MyObj;
i : integer;
begin
// you allocate memory for the collection
objCollection := MyObjCollection.Create;
for i:=0 to 10 do
begin
// you allocate memory for the object
tempObj := MyObj.Create;
// assign values to object's attributes
tempObj.attribute1 := i;
tempObj.attribute2 := '';
// and finally add it to the collection
if not objCollection.AddObj(tempObj) then Showmessage('obj number ' + intToStr(i) + ' could not be added to the collection');
end;
// to access attribute1 of an element of the collection you would write
MyObj(objCollection.items[i]).attribute1
end;
from here on, the posibilities are unlimmited. you can create your own constructors, destructors, functions and procedures for your objects (of various types) as well as collections and use them in combination.
I hope this gave you a hint on how to work with collections.