Современные технологии программирования |
Конспект лекций |
Лекция 11. Списки и контейнеры
Содержание
Пример. Список объектов класса. *
Пример. Создание списка визуальных компонентов. *
Пример использования TObjectList. *
Пример использования TObjectStack *
Пример использования TObjectQueue *
Пример использования потомка TStrings свойства Items компонента TListBox *
Источники дополнительных сведений *
Изучение библиотеки VCL невозможно без понимания нескольких входящих в неё основополагающих классов. Они служат для упорядочения хранения и доступа к данным и входят в состав многих компонентов. К ним относятся: список (TList, TObjectList), набор строк (TStrings) и поток (TStream).
Классы TSrings и TStream являются абстрактными. Их создают, чтобы собрать воедино то общее, что будет унаследовано классами потомками, и называются они так потому, что основные методы в них абстрактные. На уровне TSrings и TStream нужные свойства и методы только объявляются – они не имеют реализации.
Рис. Иерархия классов.
Класс TList – универсальный список (он описан в модуле Classes). Класс TList наследует от Tobject. Он представляет собой массив нетипированных указателей и потому годиться для хранения любых, в том числе разнотипных данных и объектов. При добавлении/удалении в список данные не создаются и не уничтожаются – эта обязанность лежит на программисте. TList включает в себя свойства и методы для:
Рисунок. Организация списка TList в памяти.
Приведём доступные ему методы и свойства:
Свойства списка Tlist |
|
property Capacity: Integer; |
Определяет максимальное количество элементов в списке. Оно может изменяться как явно – пользователем, так и при добавлении элементов в список, в том случае, когда Count>= Capacity. |
property Count: Integer; |
Содержит число элементов в списке |
property Items[Index: Integer]: Pointer; |
Возвращает указатель на содержимое элемента списка с индексом index. Это свойство является индексным свойством, принимаемым по умолчанию, и его имя при записи можно опускать. Индексация элементов списка начинается с 0, так что список начинается с элемента со значением индекса 0. |
type TPointerList = array[0..MaxListSize-1] of Pointer; PPointerList = ^TPointerList; property List: PPointerList; |
Описывает массив указателей, который составляет массив элементов. Используйте List, чтобы получить прямой доступ элементам массива. |
Методы класса Tlist |
|
function Add(Item: Pointer): Integer; |
Вставляет новый элемент в конец списка |
procedure Assign(ListA: TList; AOperator: TListAssignOp = laCopy; ListB: TList = nil); |
Копирует элементы из одного списка вдругой. |
procedure Clear; virtual; |
Удаляет все элементы из списка. Вызывайте Clear, чтобы очистить массив элементов и установить счётчик Count в ноль. Clear также освобождает память, используемую для хранения узлов списка и установки Capacity в 0. |
procedure Delete(Index: Integer); |
Удаляет элемент из позиции, заданной параметром Index. Вызов Delete перемещает все элементы в массиве элементов, которые следуют за удалённым элементом, и уменьшает Count. |
destructor Destroy; override; |
Освобождает память занимаемую списком и его узлами. Не вызывайте Destroy непосредственно. Вместо него вызывайте Free. Free анализирует значение nil. Free вызывает Destroy только тогда, когда Tlist не равен nil. |
Error |
|
procedure Exchange(Index1, Index2: Integer); |
Обменивает позициями два элемента массива элементов. Вызывайте Exchange, чтобы обменять позициями элементы в позициях Index1 и Index2 массива элементов. |
function Expand: TList; |
Увеличивает Capacity списка. Вызывайте Expand, чтобы выделить больше памяти для добавления новых узлов списка. Expand ничего не делает, если размер списка меньше Capacity. If Count = Capacity, Expand increases the Capacity of the list as follows. If the value of Capacity is greater than 8, Expand increases the Capacity of the list by 16. If the value of Capacity is greater than 4, but less than 9, the Capacity of the list increases by 8. If the value of Capacity is less than 4, the Capacity of the list grows by 4. The returned value is the expanded list object |
function Extract(Item: Pointer): Pointer; |
Удаляет указанный элемент из списка. Вызывайте Extract, чтобы удалить элемент из списка. После удаления элемента, все следующие за ним элементы перемещаются на одну позицию, и значение Count уменьшается на 1. В TList, Extract и Delete методы ведут себя совершенно одинаково. Классы потомки(включая TObjectList и TComponentList) различают оба этих метода. Для удаления ссылки на элемент списка без удаления входа в массив элементов и изменения Count, установите свойство Items в nil. |
function First: Pointer; |
Возвращает Items[0]. Вызывайте First, чтобы получить указатель на первый элемент из массива элементов. |
function IndexOf(Item: Pointer): Integer; |
Возвращает индекс первого вхождения элемента в массив элементов с заданным значением указателя. Вызывайте IndexOf, чтобы получить индекс элемента в массиве элементов по его указателю. Указатель на элемент передаётся как параметр. |
procedure Insert(Index: Integer; Item: Pointer); |
Добавляет элемент в массив элементов в позицию, заданную параметром Index. Вызывайте Insert, чтобы вставить элемент в середину массива элементов. Insert добавляет элемент в указанную позицию, смещая элемент, ранее занимавший эту позицию и все последующие элементы в сторону позиций с большими значениями индексов. Insert увеличивает Count и, если это необходимо, выделяет память, увеличивая значение Capacity. |
function Last: Pointer; |
Возвращает Items[Count - 1]. Вызывайте Last, чтобы получить указатель на последний элемент массива элементов. |
procedure Move(CurIndex, NewIndex: Integer); |
Изменяет позицию элемента в массиве элементов. Вызывайте метод, чтобы переместить элемент с позиции CurIndex в позицию NewIndex. |
procedure Pack; |
Удаляет все nil-элементы из массива Вызывайте этот метод для перемещения не nil- элементов в начало массива и уменьшения Count свойства до количества действительно существующих элементов. Метод не освобождает память из под узлов списка. |
function Remove(Item: Pointer): Integer; |
Удаляет первое вхождение ссылки на элемент в массиве. Используйте метод, когда индекс элемента не известен. Метод возвращает индекс, который элемент имел до удаления. Все следующие за ним элементы смещаются на одну позицию, значение Count уменьшается на единицу. Если список хранит несколько копий, удаляется только первая. |
procedure Sort(Compare: TListSortCompare); type TListSortCompare = function (Item1, Item2: Pointer): Integer; |
Выполняет быструю сортировку списка, на основе упорядочения, заданного функцией Compare. Compare возвращает значение < 0 если Item1 меньше, чем Item2, 0 если они равны, и значение > 0, если Item1 больше чем Item2. |
Пример. Список объектов класса.
В этом примере список заполняется объектами типа T.
program PTList;
uses
Classes;
type
//---------------------------------------------------------------------------
T = class//Элементы списка
Ch: Char;
constructor Create(c: Char);
end;
//---------------------------------------------------------------------------
constructor T.Create(c: Char);
begin
Ch:= c
end;
//---------------------------------------------------------------------------
function Compare2(Item1,Item2: Pointer): Integer;
//Упорядочение списка по убыванию
begin
Result:= Ord(T(Item2).Ch) - Ord(T(Item1).Ch)
end;
//---------------------------------------------------------------------------
function Compare1(Item1,Item2: Pointer): Integer;
//Упорядочение списка по возрастанию
begin
Result:= Ord(T(Item1).Ch) - Ord(T(Item2).Ch)
end;
//---------------------------------------------------------------------------
procedure FillDynArr(L: TList; n: integer);
//Заполнить список элементами
var i: integer;
begin
with L do for i:= 0 to n - 1 do Insert(i,T.Create(Chr(i + Ord('A'))))
end;
//---------------------------------------------------------------------------
procedure WriteDynArr(L:TList);
//Вывести список
var i:integer;
begin
with L do begin
writeln('elements: ',Count);
for i:=0 to Count-1 do
if L[i] <> nil then write(T(L[i]).Ch,',');
end;
writeln;
end;
//---------------------------------------------------------------------------
var L:TList;i:Integer;
begin
L:= TList.Create;
FillDynArr(L,5);//Создан список из 5 элементов от 0..4
WriteDynArr(L);// ABCDE : 5
L.Sort(Compare2);
WriteDynArr(L);// EDCBA : 5
L.Sort(Compare1);
WriteDynArr(L);// ABCDE : 5
L.Delete(L.Count-1);//удален элемент с индексом 4
WriteDynArr(L);// ABCD : 4
L.Add(T.Create(Chr(L.Count+Ord('A'))));//в конец добавлен элемент E
WriteDynArr(L);// ABCDE : 5
L.Delete(0);//удален элемент с индексом 0
WriteDynArr(L);// BCDE : 4
L.Insert(0,T.Create('A'));//вставлен элемент A с индексом 0
WriteDynArr(L);// ABCDE : 5
L.Insert(3,T.Create('Z'));//вставлен элемент Z с индексом 3
WriteDynArr(L);// ABCZDE : 6
L.Exchange(0,3);//обменять значениями элементы с индексами 0, 3
WriteDynArr(L);// ZBCADE : 6
L.Delete(0);//удален элемент с индексом 0
WriteDynArr(L);// BCADE : 5
L.Move(2,0);//элемент с индексом 2 перемещен на место с индексом 0
WriteDynArr(L);// ABCDE : 5
for i:= 0 to L.Count-1 do
T(L[i]).Free;
L.Clear;
WriteDynArr(L);//0 элементов
readln;
end.
Пример. Создание списка визуальных компонентов
В этом приложении пользователь может создать произвольное количество меток - компонентов класса TLabel, нажав кнопку “Добавить”. Каждый вновь созданный компонент добавляется в список. Количество меток в списке, ёмкость списка и количество компонентов отображаются на форме. Компоненты можно удалять из списка слева (Удалить первый) или справа (Удалить последний)с помощью соответствующих кнопок на форме.
unit UDynCmnt;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
AddButton: TButton;
DelFirst: TButton;
DelLast: TButton;
Elements: TEdit;
Label1: TLabel;
Label2: TLabel;
ListCapacity: TEdit;
Components: TEdit;
Label3: TLabel;
procedure FormCreate(Sender: TObject);
procedure AddButtonClick(Sender: TObject);
procedure DelFirstClick(Sender: TObject);
procedure DelLastClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure Update();
end;
var
Form1: TForm1;
L: TList;
implementation
{$R *.dfm}
procedure TForm1.Update();//обновить отображаемые данные
begin
Components.Text:= IntToStr(Form1.ComponentCount);
Elements.Text:= IntToStr(L.Count);
ListCapacity.Text:= IntToStr(L.Capacity);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
L:= TList.Create;
l.Capacity:= 20;
Update();
end;
procedure TForm1.AddButtonClick(Sender: TObject);//добавить компонент
var Lb,C: Tlabel;
begin
Lb:= TLabel.Create(Form1);
with Lb do begin
Parent:= Form1;
AutoSize:= True;
Caption:= 'Label ' + IntToStr(L.Count);
Color:= clBlue;
Height:= 24;
Left:= 15;
if L.Count > 0 then begin C:= L.Last;Top:= C.Top + 30; end
else Top:= 8;
end;
L.Add(Lb);
Update();
end;
procedure TForm1.DelLastClick(Sender: TObject);//удалить последний компонент
var Lb: TLabel;
begin
if L.Count > 0 then TLabel(L.Last).Free
else exit;
L.Remove(L.Last);
Update();
end;
procedure TForm1.DelFirstClick(Sender: TObject);//удалить первый компонент
var Lb: TLabel;
begin
if L.Count > 0 then TLabel(L.First).Free
else exit;
L.Remove(L.First);
Form1.Repaint;
Update();
end;
end.
Owner – тот объект, который при создании вызывает конструкторы всех объектов, владельцем которых он является, а при уничтожении – их деструкторы.
Используйте свойство Parent, чтобы получить или установить родителя элемента управления. Родитель элемента управления, элемент управления, который его содержит. Например, если приложение включает три радиокнопки в радиогруппе, радиогруппа – это родитель радиокнопок, а радиокнопки – дочерние элементы управления для радиогруппы.
Когда создаётся элемента управления в работающем приложении, присваивайте значение свойству Parent. Обычно это форма, панель, радиогруппа или некоторый другой элемент управления, который разработан для того, чтобы содержать другие элементы управления. Изменение свойства parent элемента управления перемещает элемент управления на экране так, что он отображается внутри нового родителя. Когда родитель перемещается, дочерний элемент управления перемещается вместе с родителем.
Этот класс описан в модуле Contnrs.
Класс TObjectList наследует от TList.
TObjectList поддерживает список объектов, владельцем которых он может быть (является по умолчанию).
Используйте TObjectList для сохранения и создания списка объектов. TObjectList обеспечивает свойства и методы для
Если свойство OwnsObjects установлено в True (по умолчанию) TObjectList управляет памятью своих объектов, освобождая объект, когда по его индексу осуществляется переприсваивание, когда объект удаляется из списка методами Delete, Remove, или Clear, или когда объект TObjectList удаляется из памяти.
Приведём доступные ему методы и свойства:
Методы и свойства TObjectList |
|
function FindInstanceOf(AClass: TClass; AExact: Boolean = True; AStartAt: Integer = 0): Integer; |
Находит первый объект описанного класса в списке. FindInstanceOf возвращает индекс первого объекта AClass, который появляется после AStartAt в массиве элементов. Если AExact есть True, FindInstanceOf возвращает объекты только самого AClass, игнорируя объекты классов наследников. Если не найден ни один объект указанного класса, FindInstanceOf returns –1. |
property OwnsObjects: Boolean; |
Позволяет TObjectList освобождать объекты, когда они удаляются из списка, или когда удаляется сам список. OwnsObjects разрешает TObjectList управлять памятью, занимаемой его объектами. Если OwnsObjects есть True (по умолчанию), вызов Delete или Remove освобождает удалённый объект вдобавок к удалению его из списка. вызов Clear освобождает все объекты в списке вдобавок к опустошению списка. вызов destructor освобождает все объекты в списке в добавление к освобождению самого TObjectList. присваивание нового значения по индексу элемента освобождает объект, который перед этим занимал эту позицию в списке. Даже если OwnsObjects есть True, метод Extract можно использовать для удаления объектов из списка без освобождения их. |
Плюс к этому все методы и свойства совпадающие по имени и назначению со свойствами класса TList |
Пример использования TObjectList.
program PTObjLst;
{$APPTYPE CONSOLE}
uses
SysUtils,
Contnrs;
type
//---------------------------------------------------------
A = class
f: integer;
constructor Create(nf: integer = 0);
end;
//---------------------------------------------------------
constructor A.Create(nf: integer = 0);
begin
f:= nf;
end;
//---------------------------------------------------------
var
L: TObjectList;
i: integer;
begin
L:= TObjectList.Create;
writeln(L.Count);
for i:= 1 to 5 do L.Add(A.Create(i));
writeln(L.Count);
for i:= 1 to 5 do writeln((L[i - 1] as A).f);
L.Clear;
writeln(L.Count);
readln;
{ TODO -oUser -cConsole Main : Insert code here }
end.
Вывод на экран для примера, приведённого выше, будет иметь следующий вид:
0
5
1
2
3
4
5
0
Иерархия классов.
TOrderedList наследует от класса Tobject.
TOrderedList абстрактный класс, который представляет список нетипированных указателей.
Этот класс описан в модуле Contnrs.
Классы-потомки подобные TStack и TQueue перекрывают protected метод PushItem для задания порядка доступа к элементам.
TStack наследует от TOrderedList.
Класс TStack поддерживает принцип обслуживания: первым вошёл – последним вышел для массива нетипированных указателей.
Этот класс описан в модуле Contnrs.
Используйте объект TStack для сохранения и поддержки принципа обслуживания: первым вошёл – последним вышел списка нетипированных указателей.
Методы класса TStack |
|
procedure Push(AItem: Pointer); |
Добавляет элемент в список. Вызывайте Push, чтобы добавить элемент в список. Чтобы получить элемент, добавленный методом Push, вызывайте методы Pop или Peek. |
function Pop: Pointer; |
Удаляет и возвращает следующий элемент списка. Вызывайте Pop, чтобы выделить элемент из списка. Pop выделяет следующий элемент из списка, затем возвращает указатель на удалённый элемент. Каждый потомок TOrderedList реализует Pop для удаления и возвращения определённого элемента из списка. Например, TQueue возвращает элемент, который был добавлен первым, в то время, как TStack, возвращает элемент, который был добавлен последним. Чтобы получить доступ к элементу без его удаления, вызывайте Peek. |
function Peek: Pointer; |
Возвращает указатель на следующий элемент в списке. Вызывайте Peek, чтобы получить доступ к списку без удаления элемента. Peek возвращает указатель на следующий элемент в списке (элемент с вершины). Каждый потомок TOrderedList реализует Pop для удаления и возвращения определённого элемента из списка. Например, TQueue возвращает элемент, который был добавлен первым, в то время, как TStack, возвращает элемент, который был добавлен последним Для удаления элемента из списка используйте Pop. |
function AtLeast(ACount: Integer): Boolean; |
Проверяет размер списка. Вызывайте AtLeast, чтобы проверить размер списка. AtLeast возвращает True, если количество элементов в списке больше или равно ACount. |
function Count: Integer; |
Возвращает размер списка. Count возвращает число элементов в списке. |
constructor Create; |
Создаёт объект типа TStack. Create создаёт новый список. |
destructor Destroy; override; |
Удаляет объект типа TStack. Не вызывайте Destroy непосредственно, вызывайте Free. Если Free определит, что указатель на TStack не nil, толькотогда он вызывает Destroy. Destroy освобождает память, используемую для хранения объекта TStack. Он не освобождает память, на которую указывают элементы списка. |
//---------------------------------------------------------
program PTObjStack;
{$APPTYPE CONSOLE}
uses
SysUtils, Contnrs;
type
//---------------------------------------------------------
A = class
f: integer;
constructor Create(nf: integer = 0);
end;
//---------------------------------------------------------
constructor A.Create(nf: integer = 0);
begin
f:= nf;
end;
//---------------------------------------------------------
var
S: TStack;
o: A;
i: integer;
begin
S:= TStack.Create;//Создаём стек нетипированных указателей
writeln(S.Count);//В списке обектов 0 (нет)
for i:= 1 to 5 do S.Push(A.Create(i));//Заносим 5 обектов
//(типа А)
writeln(S.Count);//В списке обектов 5
for i:= 1 to 5 do
begin
write(A(S.Peek).f,', ');//Значение элемента на вершине
//стека
o:=S.Pop; //Извлекаем объект из стека
writeln(o.f);//Значение поля извлечённого объекта
o.Free;//Удаляем объект из памяти
end;
writeln(S.Count);//В списке обектов 0 (нет)
S.Free;//Удаляем стек из памяти
readln;
end.
//---------------------------------------------------------
Вывод на экран для примера, приведённого выше, будет иметь следующий вид:
0
5
5, 5
4, 4
3, 3
2, 2
1, 1
0
TObjectStack наследует от TStack.
TObjectStack поддерживает список объектов по принципу обслуживания первым пришёл – последним обслужен (стек).
Этот класс описан в модуле Contnrs.
Используйте класс TObjectStack для сохранения и обслуживания объектов по принципу стека.
Методы класса TObjectStack |
|
function Peek: TObject; |
Возвращает указатель на вершину стека. Вызывайте Peek, чтобы получить доступ к стеку, без удаления объекта. Peek возвращает указатель на следующий объект в стеке (то есть, на последний добавленный объект). Для удаления объекта из стека используйте Pop. |
function Pop: TObject; |
Удаляет и возвращает объект с вершины стека. Вызывайте Pop для выделения объекта из стека. Pop удаляет следующий объект из стека (то есть, последний добавленный объект), затем возвращает указатель на удалённый объект). Для доступа к стеку без удаления объекта вызывайте Peek. |
procedure Push(AObject: TObject); |
Добавляет объект на вершину стека. Вызывайте Push, чтобы добавить элемент в стек. Для выделения объекта, добавленного с помощью Push, вызывайте Pop или Peek. |
Пример использования TObjectStack
//---------------------------------------------------------
program PTObjStack;
{$APPTYPE CONSOLE}
uses
SysUtils, Contnrs;
type
//---------------------------------------------------------
A = class
f: integer;
constructor Create(nf: integer = 0);
end;
//---------------------------------------------------------
constructor A.Create(nf: integer = 0);
begin
f:= nf;
end;
//---------------------------------------------------------
var
S: TObjectStack;
i: integer;
begin
S:= TObjectStack.Create;//Создаём стек объектов
writeln(S.Count);//В списке обектов 0 (нет)
for i:= 1 to 5 do S.Push(A.Create(i));//Заносим 5 обектов
//(типа А)
writeln(S.Count);//В списке обектов 5
for i:= 1 to 5 do
begin
write((S.Peek as A).f,', ');//Значение элемента на вершине
//стека
writeln((S.Pop as A).f);//Извлекаем объекты из стека
end;
writeln(S.Count);//В списке обектов 0 (нет)
S.Free;//Удаляем стек из памяти
readln;
end.
//---------------------------------------------------------
Вывод на экран для примера, приведённого выше, будет иметь следующий вид:
0
5
5, 5
4, 4
3, 3
2, 2
1, 1
0
TQueue наследует от TOrderedList.
Этот класс описан в модуле Contnrs.
Класс TQueue поддерживает принцип обслуживания: первым вошёл – первым вышел для массива нетипированных указателей.
Этот класс описан в модуле Contnrs.
Используйте объект TQueue для сохранения и поддержки принципа обслуживания: первым вошёл – первым вышел списка нетипированных указателей.
Методы класса TQueue |
|
procedure Push(AItem: Pointer); |
Добавляет элемент в список. Вызывайте Push, чтобы добавить элемент в список. Чтобы получить элемент, добавленный методом Push, вызывайте методы Pop или Peek. |
function Pop: Pointer; |
Удаляет и возвращает следующий элемент списка. Вызывайте Pop, чтобы выделить элемент из списка. Pop выделяет следующий элемент из списка, затем возвращает указатель на удалённый элемент. Каждый потомок TOrderedList реализует Pop для удаления и возвращения определённого элемента из списка. Например, TQueue возвращает элемент, который был добавлен первым, в то время, как TStack, возвращает элемент, который был добавлен последним. Чтобы получить доступ к элементу без его удаления, вызывайте Peek. |
function Peek: Pointer; |
Возвращает указатель на следующий элемент в списке. Вызывайте Peek, чтобы получить доступ к списку без удаления элемента. Peek возвращает указатель на следующий элемент в списке. Каждый потомок TOrderedList реализует Pop для удаления и возвращения определённого элемента из списка. Например, TQueue возвращает элемент, который был добавлен первым, в то время, как TStack, возвращает элемент, который был добавлен последним Для удаления элемента из списка используйте Pop. |
function AtLeast(ACount: Integer): Boolean; |
Проверяет размер списка. Вызывайте AtLeast, чтобы проверить размер списка. AtLeast возвращает True, если количество элементов в списке больше или равно ACount. |
function Count: Integer; |
Возвращает размер списка. Count возвращает число элементов в списке. |
constructor Create; |
Создаёт объект типа TQueue. Create создаёт новую очередь TQueue. |
destructor Destroy; override; |
Удаляет объект типа TQueue. Не вызывайте Destroy непосредственно, вызывайте Free. Если Free определит, что указатель на TQueue не nil, толькотогда он вызывает Destroy. Destroy освобождает память, используемую для хранения объекта TQueue. Он не освобождает память, на которую указывают элементы списка. |
//---------------------------------------------------------
Program PTQueue;
{$APPTYPE CONSOLE}
uses
SysUtils,
Contnrs;
type
//---------------------------------------------------------
A = class
f: integer;
constructor Create(nf: integer = 0);
end;
//---------------------------------------------------------
constructor A.Create(nf: integer = 0);
begin
f:= nf;
end;
//---------------------------------------------------------
var
Q: TQueue;
o: A;
i: integer;
begin
Q:= TQueue.Create;//Создаём очередь нетипированных указателей
writeln(Q.Count);//В очерди обектов 0 (нет)
for i:= 1 to 5 do Q.Push(A.Create(i));//Заносим 5 обектов
//(типа А)
writeln(Q.Count);//В очередие обектов 5
for i:= 1 to 5 do
begin
write(A(Q.Peek).f,', ');//Значение элемента на вершине
//очереди
o:=Q.Pop; //Извлекаем объект из очереди
writeln(o.f);//Значение поля извлечённого объекта
o.Free;//Удаляем объект из памяти
end;
writeln(Q.Count);//В списке обектов 0 (нет)
Q.Free;//Удаляем очередь из памяти
readln;
end.
//---------------------------------------------------------
Вывод на экран для примера, приведённого выше, будет иметь следующий вид:
0
5
1, 1
2, 2
3, 3
4, 4
5, 5
0
TObjectQueue наследует от TQueue.
Этот класс описан в модуле Contnrs.
TObjectQueue поддерживает список объектов по принципу обслуживания: первым пришёл – первым обслужен (очередь).
Используйте класс TObjectQueue для сохранения и обслуживания объектов по принципу очереди.
Методы класса TObjectQueue |
|
function Peek: TObject; |
Возвращает указатель на начало очереди. Вызывайте Peek, чтобы получить доступ к очереди, без удаления объекта. Peek возвращает указатель на следующий объект в очереди (то есть, на объект, добавленный первым). Для удаления объекта из стека используйте Pop. |
function Pop: TObject; |
Удаляет и возвращает объект из начала очереди. Вызывайте Pop для выделения объекта из очереди. Pop удаляет следующий объект из очереди (то есть, объект, добавленный первым), затем возвращает указатель на удалённый объект). Для доступа к очереди без удаления объекта вызывайте Peek. |
procedure Push(AObject: TObject); |
Добавляет объект в конец очереди. Вызывайте Push, чтобы добавить элемент в очередь. Для выделения объекта, добавленного с помощью Push, вызывайте Pop или Peek. |
Пример использования TObjectQueue
//---------------------------------------------------------
program PTObjQueue;
{$APPTYPE CONSOLE}
uses
SysUtils,
Contnrs;
type
//---------------------------------------------------------
A = class
f: integer;
constructor Create(nf: integer = 0);
end;
//---------------------------------------------------------
constructor A.Create(nf: integer = 0);
begin
f:= nf;
end;
//---------------------------------------------------------
var
Q: TObjectQueue;
i: integer;
begin
Q:= TObjectQueue.Create;
writeln(Q.Count);
for i:= 1 to 5 do Q.Push(A.Create(i));
writeln(Q.Count);
for i:= 1 to 5 do
begin write((Q.Peek as A).f,', ');writeln((Q.Pop as A).f); end;
writeln(Q.Count);
Q.Free;
readln;
end.
//---------------------------------------------------------
Вывод на экран для примера, приведённого выше, будет иметь следующий вид:
0
5
1, 1
2, 2
3, 3
4, 4
5, 5
0
TStringList поддерживает список строк. Этот класс описан в модуле Classes.
Используйте объект список строк для хранения и манипулирования списком строк. TStringList реализует абстрактные свойства и методы, введённые в классе TStrings, и вводит новые свойства, событийные процедуры и методы для
TStringList не является владельцем объектов, помещённых в список. За удаление их из памяти отвечает приложение.
Организация списка на уровне памяти представлена ниже на рисунке.
Свойства и методы класса TStringList |
|
property Capacity: Integer; |
Показывает количество строк в списке строк, для хранения которых выделена память. Используйте Capacity для определения количества памяти доступной для хранения строк, или для перераспределения памяти для большего или меньшего числа строк. Capacity – это количество выделенных входов в список строк, в противоположность с Count, который определяет число строк в списке. Таким образом, Capacity больше или равно Count. Adding new strings will cause the Capacity property to increase if necessary, but setting the Capacity property will not change the Count property. Do not set Capacity to a value less than Count, or the list will be truncated and Count will indicate that the list contains more strings than is the case. Also, if Capacity is set to a value less than Count, the memory used to store the strings that are dropped from the list (as opposed to the entries in the list that point to those strings) is not freed. |
property CaseSensitive: Boolean; |
Управляет поиском, сортировкой, определением дубликатов – будет ли учитываться регистр. Используйте CaseSensitive, чтобы указать сравнивать ли строки с учётом или без учёта регистра. Установите CaseSensitive в True, что бы выполнять поиск в списке строк, отыскание дубликатов, сортировку строк списка с учётом регистра. Установите CaseSensitive в False, чтобы выполнять преобразование списка строк этими операциями без учёта регистра. |
property Count: Integer; |
Указывает число строк в списке. Используйте Count для выполнения последовательных преобразований над всеми строками списка строк |
property Duplicates: TDuplicates; |
Определяет можно ли добавлять в сортируемый список дубликаты строк. Установите Duplicates, чтобы определить, что должно случиться, при попытке добавить дубликат в сортируемый список. Свойство CaseSensitive управляет тем, будут ли две строки считаться дубликатами, если они идентичны, исключая разницу в регистрах символов. Значение Duplicates может быть одним из следующих. Константа означает: dupIgnore игнорировать попытки добавления дубликатов в список строк. dupError Возбуждать EStringListError исключение, когда выполнены попытки добавить дубликаты строк в сортируемый список. dupAccept Разрешить дубликаты строк в сортируемом списке. Установите Duplicates перед добавлением строк в список. Установка Duplicates в dupIgnore или dupError не вызывает никаких действий по отношению к дубликатам строк уже находящихся в списке. Примечание: Duplicates ничего не значит, если список не сортируемый. |
property Objects[Index: Integer]: TObject; |
Перечисляет набор объектов, каждый из которого ассоциирован со строкой из свойства Strings. Для доступа к объекту, ассоциированному со строкой, через свойство Objects, используйте те же индексы, что для доступа к соответствующей ему строке из свойства Strings. Просматривайте объект, ассоциированный со строкой, читая свойство Objects с индексом строки. Индекс задаёт позицию строки ассоциированной с объектом, где 0 – индекс первой строки, 1 – второй и т.д. Используйте метод IndexOf чтобы найти индекс строки. Например, используйте Objects, чтобы связать графические объекты со строками в списке строк. The Objects property then enables the application to quickly locate the bitmaps for display beside the strings in a listbox, or for drawing when the associated string is selected in a control. Замечание: Объект TStringList не является владельцем объектов, помещённых в массив объектов. Объекты, добавленные в массив объектов, существуют, даже если список строк удалён. Они должны быть удалены приложением. |
property Sorted: Boolean; |
Описывает, будут ли автоматически сортироваться строки в списке. Установите Sorted в True, чтобы строки в списке автоматически сортировались в порядке возрастания. Установите Sorted в False, чтобы позволить строкам оставаться там, куда они вставлены. Когда Sorted есть False, строки в списке могут быть расставлены в возрастающем порядке в любой момент вызовом метода Sort. Когда Sorted в True, не используйте Insert для добавления строк в список. Вместо этого, используйте Add, который будет вставлять новые строки в соответствующем порядке. Когда Sorted в False, используйте Insert, чтобы добавлять строки в произвольную позицию списка, или Add, чтобы добавлять строки в конец списка. Note: Свойство CaseSensitive, управляет правилом сортировки строк в списке: с учётом или без учёта регистра. Порядок сортировки зависит от системы, под управлением которой работает приложение. |
property Strings[Index: Integer]: string; default; |
Список строк, на которые можно ссылаться с помощью индекса. Индексация начинается с нуля. Используйте Strings, чтобы читать или изменять строки в произвольной позиции. Index задаёт позицию строки, где 0 – это позиция первой строки, 1 – это позиция второй строки и т. д. Чтобы найти индекс строки в списке, вызывайте метод IndexOf. Strings – это свойство по умолчанию для объектов типа список строк. Идентификатор Strings можно опустить при обращении к свойству Strings объекта список строк. Например, следующие две строки кода приемлемы и делают одно и тоже: MyStringList.Strings[0] := 'This is the first string'; MyStringList[0] := 'This is the first string'; |
function Add(const S: string): Integer; override; |
Добавляет новую строку в список. Вызывайте Add, чтобы добавить строку к списку. Если список сортируемый, S добавляется в соответствующую позицию в порядке сортировки. Если список не сортируемый, S добавляется в конец списка. Add возвращает позицию элемента в списке, где для первого элемента в списке значение 0. Замечание: Для сортируемых списков, Add возбудит исключение EListError если строка S уже есть в списке и Duplicates установлено в dupError. Если Duplicates установлено в dupIgnore, попытка добавления в список дубликата строки ничего не изменит. |
function AddObject(const S: string; AObject: TObject): Integer; override; |
Добавляет к списку строку и ассоциированный со строкой объект. Вызывайте AddObject, чтобы добавить строку и ассоциированный с ней объект в список. AddObject возвращает индекс новой строки и объекта. Замечание: Объект TStringList не является владельцем объектов, которые вы к нему добавляете. Объекты, добавляемые к TStringList, существуют, даже если объект TStringList удалён. Их должно удалить приложение. |
Пример использования потомка TStrings свойства Items компонента TListBox
unit UTStringList;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Contnrs;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton;//Добавить
Button2: TButton;//Удалить
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
//Добавить список
var s: String;
begin
s:= 'Список ' + IntTostr(ListBox1.Items.Count + 1);
ListBox1.Items.AddObject(S,TObjectList.Create);
end;
//------------------------------------------------------------
procedure TForm1.Button2Click(Sender: TObject);
//Удалить список
var L: TObjectList;
begin
if ListBox1.Count <> 0 then
begin
L:= ListBox1.Items.Objects[ListBox1.Items.Count - 1] as TObjectList;
L.Free;
ListBox1.Items.Delete(ListBox1.Items.Count - 1);
end;
end;
//------------------------------------------------------------
end.
Источники дополнительных сведений