TList: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: TList
| Old | New | Line | |
|---|---|---|---|
| 1 | + | ## TList or TFPList | |
| 2 | + | ||
| 3 | + | TList is a class that can be used to manage collections of pointers. It introduces methods and properties to store the pointers, search in the list of pointers, sort them. It manages its memory by itself, no intervention for that is needed (but, of course, it does not manage the memory of what ever your pointers point to). It has an event notification mechanism which allows to notify of list changes. This slows down some of TList mechanisms, and if no notification is used, TFPList may be used instead. | |
| 4 | + | ||
| 5 | + | Both TList and TFPList are declared in classes and that usually is already in your uses clause. | |
| 6 | + | ||
| 7 | + | The 'managed pointers' may conveniently point to, for example, records, just about any record you care to define. | |
| 8 | + | ||
| 9 | + | Here is a very basic unit that will manage a set of notes about some friends of mine - | |
| 10 | + | ||
| 11 | + | ``` pascal | |
| 12 | + | type | |
| 13 | + | PNote=^TNote; | |
| 14 | + | TNote = record | |
| 15 | + | Name : ANSIString; | |
| 16 | + | IsSilly : boolean; | |
| 17 | + | NumbHeads : integer; | |
| 18 | + | end; | |
| 19 | + | ||
| 20 | + | type | |
| 21 | + | // Note we can use TFPList (faster) or TList (and get event notification) | |
| 22 | + | TNoteList = class(TList) | |
| 23 | + | private | |
| 24 | + | function Get(Index: integer): PNote; | |
| 25 | + | public | |
| 26 | + | destructor Destroy; override; | |
| 27 | + | function Add(ANote : PNote) : integer; | |
| 28 | + | function FindName(const Name : ANSIString) : PNote; | |
| 29 | + | property Items[Index: integer]: PNote read Get; default; | |
| 30 | + | end; | |
| 31 | + | ||
| 32 | + | implementation | |
| 33 | + | ||
| 34 | + | function TNoteList.Get(Index: integer): PNote; | |
| 35 | + | begin | |
| 36 | + | Result := PNote(inherited get(Index)); | |
| 37 | + | end; | |
| 38 | + | ||
| 39 | + | function TNoteList.Add(ANote: PNote): integer; | |
| 40 | + | begin | |
| 41 | + | result := inherited Add(ANote); | |
| 42 | + | end; | |
| 43 | + | ||
| 44 | + | function TNoteList.FindName(const Name: ANSIString): PNote; | |
| 45 | + | var | |
| 46 | + | P : PNote; | |
| 47 | + | begin | |
| 48 | + | Result := Nil; | |
| 49 | + | for P in self do | |
| 50 | + | if P^.Name = Name then exit(P); | |
| 51 | + | end; | |
| 52 | + | ||
| 53 | + | destructor TNoteList.Destroy; | |
| 54 | + | var | |
| 55 | + | I : integer; | |
| 56 | + | begin | |
| 57 | + | for I := 0 to Count-1 do begin | |
| 58 | + | dispose(Items[I]); | |
| 59 | + | end; | |
| 60 | + | inherited Destroy; | |
| 61 | + | end; | |
| 62 | + | .... | |
| 63 | + | ``` | |
| 64 | + | ||
| 65 | + | In this example, that can use either TList or TFPList, we make a record that will hold one "item of data", and, to make things easy, we also declare a type pointer to that sort of record. Its sensible to put code like this in its own unit, a practical use will almost certainly require a few extra methods to manage the data it self. | |
| 66 | + | ||
| 67 | + | To use this example, we need to declare a variable of type TNoteList and then create and destroy it. So, perhaps in a FormCreate we would have - | |
| 68 | + | ||
| 69 | + | ``` pascal | |
| 70 | + | NoteList := TNoteList.Create; | |
| 71 | + | ``` | |
| 72 | + | ||
| 73 | + | and in FormDestroy we might have - | |
| 74 | + | ||
| 75 | + | ``` pascal | |
| 76 | + | NoteList.free; | |
| 77 | + | ``` | |
| 78 | + | ||
| 79 | + | To load some data we would perhaps use - | |
| 80 | + | ||
| 81 | + | ``` pascal | |
| 82 | + | ||
| 83 | + | procedure AddNote(N: string; Silly: boolean; NHeads: integer); | |
| 84 | + | var | |
| 85 | + | aPRec : PNote; // Not a record, just a pointer to one. | |
| 86 | + | begin | |
| 87 | + | new(aPRec); | |
| 88 | + | aPRec^.Name := N; | |
| 89 | + | aPRec^.IsSilly := Silly; | |
| 90 | + | aPRec^.NumbHeads := NHeads; | |
| 91 | + | NoteList.Add(aPRec); | |
| 92 | + | end; | |
| 93 | + | ||
| 94 | + | procedure TForm1.LoadData(); | |
| 95 | + | begin | |
| 96 | + | AddNote('Joe', False, 1); | |
| 97 | + | AddNote('Harry', True, 1); | |
| 98 | + | AddNote('David', True, 2); // Tasmanian | |
| 99 | + | AddNote('Boris', False, 1); | |
| 100 | + | end; | |
| 101 | + | ``` | |
| 102 | + | ||
| 103 | + | and to use that data we might have - | |
| 104 | + | ||
| 105 | + | ``` pascal | |
| 106 | + | procedure TForm1.UseData(); | |
| 107 | + | var | |
| 108 | + | P : PNote; // P is a pointer to a note record, somewhere ! | |
| 109 | + | begin | |
| 110 | + | P := NoteList.FindName('David'); | |
| 111 | + | if P <> nil then | |
| 112 | + | writeln('David has ' + P^.NumbHeads.ToString + ' heads'); | |
| 113 | + | for P in NoteList do | |
| 114 | + | if P^.IsSilly then | |
| 115 | + | writeln(P^.Name + ' is silly'); | |
| 116 | + | if NoteList.FindName('George') = nil then | |
| 117 | + | writeln('George is not listed'); | |
| 118 | + | end; | |
| 119 | + | ``` | |
| 120 | + | ||
| 121 | + | ## See also | |
| 122 | + | ||
| 123 | + | - [[Data Structures, Containers, Collections]] | |
| 124 | + | - An [[AVL Tree]] will be faster. | |
| 125 | + | ||
| 126 | + | --- | |
| 127 | + | *From the Free Pascal wiki, page "TList", as it stood on 2023-10-24 after a change by Bart, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* | |
| 128 | + | Category: FPC | |
| 129 | + | Category: RTL |
