Написать эту статью побудил меня вопрос начинающего программиста: «А чем коллекция отличается от базы данных?». Коллекция, грубо говоря, это склад переменных, который, как и всякий склад, позволяет проделывать все складские операции: добавлять, удалять, вставлять, извлекать. В отличие от базы данных коллекция проживает в ОЗУ, а не на диске, зато работает на несколько порядков быстрее. Хотя, как правило, и не осуществляет контекстный поиск. Коллекция – это тоже тип переменной, поэтому коллекция может хранить другие коллекции. Многие среды имеют прототипы коллекций, которые позволяют организовывать самые замысловатые хранилища. Рассмотрим?
В качестве примера я взял хорошо известную среду Builder C++. Организуем коллекцию из каких-нибудь структур, содержащих массивы, например, таких:
struct TParamsStruct
{
int ParamsDate;
int hhi;
float Params[23];
bool bParams[23];
};
Структура может быть другой и сколь угодно сложной. Создадим новый тип переменной – коллекцию этих структур TparamsStructList. В заголовочном файле имя.h опишем наследование элемента коллекции и самой коллекции из родительских классов TСollectionItem и TСollection:
class TParamsStructItem : public TCollectionItem
// элемент коллекции:
{
private:
struct TParamsStruct FValue;
public:
__fastcall TParamsStructItem(TCollection *Collection);
__property TParamsStruct Value = {read = FValue, write = FValue};
};
class TParamsStructList : public TCollection
// коллекция структур
{
private:
public:
TParamsStruct __fastcall GetItem(int Index);
void __fastcall SetItem(int Index, TParamsStruct AValue);
__fastcall TParamsStructList(); // конструктор
void __fastcall Add(TParamsStruct AValue);
void __fastcall Delete(int Index);
__property TParamsStruct Items[int Index] = {read = GetItem, write = SetItem};
};
В тексте программы в файле имя.cpp опишем конструкторы потомков и реализации собственных функций:
__fastcall TParamsStructItem::TParamsStructItem(TCollection *Collection) : TCollectionItem(Collection), FValue()
// создаём класс TParamsStructItem, как потомок класса TCollectionItem
{
}
__fastcall TParamsStructList::TParamsStructList() : TCollection( __classid(TParamsStructItem) )
// класс TParamsStructList передаёт своё имя в конструктор базового класса TCollection
{
}
void __fastcall TParamsStructList::Add(TParamsStruct AValue)
// Метод Add создаёт нов. экземпляр класса TParamsStructItem и добавляет его в коллекцию
{
TParamsStructItem *Item = (TParamsStructItem *) TCollection::Add();
Item->Value = AValue;
}
TParamsStruct __fastcall TParamsStructList::GetItem(int Index)
// метод чтения элемента по его индексу:
{
TParamsStructItem *Item = (TParamsStructItem *) TCollection::GetItem(Index);
return Item->Value;
}
void __fastcall TParamsStructList::SetItem(int Index, TParamsStruct AValue)
// метод записи элемента по его индексу:
{
TParamsStructItem *Item = (TParamsStructItem *) TCollection::GetItem(Index);
Item->Value = AValue;
}
Всё! Остаётся только при запуске программы создать коллекцию ParamsList:
TParamsStructList* ParamsList = new TparamsStructList;
и, конечно, хотя бы одну живую структуру:
struct TParamsStruct ParamsStruct ;
Затем можно наполнить эту структуру и многократно наслаждаться,:
ParamsList->Add(ParamsStruct);
Можно и так:
ParamsList->SetItem(ParamsStruct, i);
Или так:
ParamsList->InsertItem(ParamsStruct, i);
В одном случае вы измените содержимое элемента коллекции, в другом – вставите элемент между существующими с переиндексацией. Количество элементов в коллекции всегда можно узнать:
int Count = ParamsList->Count;
Стоп, стоп! А откуда возьмётся содержимое структуры ParamsStruct? А это уже на ваше усмотрение – либо из базы данных, либо из внешнего мира. Наполнив коллекцию, можно работать:
ParamsStruct = ParamsList->GetItem(i);
Можно выдернуть любое содержимое из коллекции, например:
float Param_i_j = ParamsList->GetItem(i).Params[j]
При необходимости коллекцию можно опустошить:
ParamsList->Clear();
Очень удобно многомерные динамические массивы организовывать в виде вложенных коллекций. Это избавляет от трудноуловимых ошибок, характерных для «олдскульных» программистов, например, попыток извлечь несуществующие данные или что-то вставить за пределами границ массивов. Коллекции избавляют программиста от ручной уборки мусора даже в таких старых языках, как С++. Программисты со стажем, работающие с базами данных, хорошо знают: если хочешь, чтобы программа «летала» – используй коллекции.
Если эта статья кому-то в чем-то оказалась полезной – автор выполнил свою задачу.
Mike
Горячие темы