Классы TStrings и TStringList – наборы строк и объектов

Класс TStrings.Абстрактный класс TStrings инкапсулирует поля и методы для работы с наборами строк. От него порождены многочисленные специализированные потомки, обслуживающие наборы строк в таких компонентах, как TComboBox, TListBox, TRichEdit и др. Эти классы (TComboBoxStrings, TListBoxStrings, TRichEditStringsи др.) объявляются в разделах Implementation соответствующих модулей (StdCtrls, СomCtrls и др.) и поэтому скрыты от браузера Delphi и не включены в справочную службу. Единственным доступным наследником TStrings является TStringList - полнофункциональный класс общего назначения.

Замечательной особенностью TStrings и его потомков является то обстоятельство, что элементами наборов служат пары строка-объект, в которых строка - собственно строка символов, а объект - объект любого класса Delphi. Такая двойственность позволяет сохранять в TStrings объекты с текстовыми примечаниями, сортировать объекты, отыскивать нужный объект по его описанию и т.д. Кроме того, в качестве объекта может использоваться потомок от TStrings, что позволяет создавать многомерные наборы строк.

Набор строк технически реализуется подобно TList - в виде массива указателей. Свойство Capacity показывает текущую длину этого массива, а свойство Count - количество элементов, занятых в нем. Свойство CommaText интерпретирует содержимое набора строк в виде одной длинной строки с элементами вида "первая строка", "вторая строка", "третья строка" и т. д. (каждая строка набора заключается в двойные кавычки и отделяется от соседней строки запятой; если в строке встречается символ “"”, он удваивается). Свойство Text интерпретирует содержимое набора в виде одной длинной строки с элементами, разделенными стандартным признаком Eoln (#13#10). Методы Add, Append, Insert, Clear и т.п. в классе TStrings - абстрактные. Связано это с тем, что класс инкапсулирует их и таким образом делает доступными во всех потомках, но он при этом не накладывает никаких ограничений на то, как располагаются в памяти строки и объекты. Каждый потомок решает эту задачу наиболее удобным для него способом.

Класс TStringList.TStringList представляет собой полнофункциональный класс общего назначения и является прямым потомкам TStrings. Помимо перекрытых абстрактных методов своего родителя класс включает в себя такие дополнительные методы и свойства (табл. 21):

Таблица 21

property Duplicates: TDuplicates; Свойство, позволяющее управлять возможностью размещения в наборе двух и более идентичных строк
property Sort: Boolean; Признак необходимости сортировки строк в алфавитном порядке
property OnChange: TNotifyEvent;; Определяет реакцию на изменение набора строк. Возникает после последнего изменения
property OnChanging: TNotifyEvent Определяет реакцию на изменение набора строк. Возникает до очередного изменения
function Find(const S:String; var Index: Integer) : Boolean; Ищет в наборе строку S и в случае успеха в параметре Index возвращает ее индекс

При Sort = True строки набора автоматически сортируются в алфавитном порядке. При этом свойство Duplicates разрешает коллизию, связанную с добавлением в набор строки, идентичной одной из ранее вставленных. Если Duplicates = DuIgnore, идентичная строка отвергается и программе ничего об этом не сообщается; если Duplicates = DuError, возбуждается исключение EListError; значение Duplicates = DuAccept разрешает вставлять в набор сколько угодно идентичных строк.

Строки в 32-разрядных Windows сортируются не с учетом внутреннего кода символа, а с учетом «смысла»: в начале располагаются все знаки препинания и разного рода «мусор», затем идут цифры, буквы латинского алфавита и символы кириллицы. Буквы упорядочены парами - сначала заглавная, за ней строчная. «Виновником» такой сортировки является API-функция AnsiCompareText, к которой обращается метод TStringList.Quicksort.

Отсортировать строки в поле Memo1 можно следующим образом:

Var str:TSTringList; i:integer;

Begin

str:=TStringList.Create;

For i:=0 to Memo1.Lines.Count-1 do

str.Add(Memo1.Lines[i]);

str.Sort;

Memo1.Lines.Clear;

For i:=0 to str.Count-1 do Memo1.LineS.Add(str[i]);

str.Free;

End;

Наши рекомендации