Шаг 67.
Библиотека Qt.
Словари QMap<K,T>, QMultiMap<K,T>

    На этом шаге рассмотрим cловари QMap<K,T>, QMultiMap<K,T>.

    Словари, в принципе, похожи на обычные, используемые в повседневной жизни. Они хранят элементы одного и того же типа, индексируемые ключевыми значениями. Главное достоинство словаря в том, что он позволяет быстро получать значение, ассоциированное с заданным ключом. Ключи должны быть уникальными (рис. 1а), за исключением мультисловаря, который допускает дубликаты (рис. 1б).


Рис.1. Словарь (а) и мультисловарь (б)

    В контейнеры этого типа заносятся элементы вместе с ключами, по которым их можно найти и которыми могут выступать значения любого типа. В случае со словарем QMap<K,T> необходимо следить за тем, чтобы не было занесено двух разных элементов с одинаковым ключом, ведь в таком случае один из этих элементов невозможно будет отыскать. Каждый ключ словаря QMap<K,T> должен быть уникален.

    При создании объекта класса QMap<K,T> нужно передать его размер в конструктор. Этот размер не является, как это принято в других контейнерных классах, размером, ограничивающим максимальное количество элементов, а представляет собой количество позиций. Количество позиций должно быть больше количества элементов, ожидаемых для хранения, иначе поиск элементов в словаре будет проводиться недостаточно эффективно. Желательно, чтобы это значение относилось к разряду простых чисел, т. к. в этом случае размещение элементов будет более удобным. Таблица 1 содержит некоторые из методов класса QMap<K,T>.

Таблица 1. Некоторые методы контейнера QMap<K,T>
Метод
Описание
lowerBound()
Возвращает итератор, указывающий на первый элемент с заданным ключом
toStdMap()
Возвращает стандартный словарь STL с элементами, находящимися в объекте QMap<T>
upperBound()
Возвращает итератор, указывающий на последний элемент с заданным ключом

    Одним из самых частых способов обращения к элементам словаря является использование ключа в операторе []. Но можно обойтись и без него, т. к. ключ и значение можно получить с помощью методов итератора key() и value(), например:

QCoreApplication a(argc, argv);
QMap<QString, QString> mapPhbook;
mapPhbook["Olga"] = "+79128795566";
mapPhbook["Gleb"] = "+79195489785";
mapPhbook["Oleg"] = "+79125487898";
QMap<QString, QString>::iterator it = mapPhbook.begin();
for (;it != mapPhbook.end(); ++it)
{
    qDebug() << "Name: " << it.key() << " Phone: " << it.value();
}


Рис.2. Результат работы программы

    Файлы приложения можно взять здесь.

    Особое внимание следует обратить на использование оператора [], который может использоваться как для вставки, так и для получения значения элемента. Но надо быть осторожным, т. к. задание ключа, для которого элемент не существует, приведет к тому, что элемент будет создан. Чтобы избежать этого, нужно проверять существование элемента, привязанного к ключу. Подобную проверку можно осуществить при помощи метода contains(). Например:

if(mapPhonebook.contains("Oleg"))
{
   qDebug() << "Phone:" << mapPhbook["Oleg"];
} 

    На практике случается так, что нужно внести сразу несколько телефонных номеров для одного и того же человека, например его домашний, рабочий и мобильный телефоны. В этом случае обычный словарь QMap<K,T> уже не подходит. Для этого нам будет необходимо воспользоваться мультисловарем QMultiMap<K,T>. Подобный пример показан на рис. 1б, снабдим его программным кодом и узнаем телефонные номера для "Gleb":

QMultiMap<QString, QString> mapPhbook;
mapPhbook.insert("Olga", "+79128795566");
mapPhbook.insert("Gleb", "+79195489785");
mapPhbook.insert("Gleb", "+79195489788");
mapPhbook.insert("Gleb", "+79128788899");
mapPhbook.insert("Oleg", "+79125487898");
mapPhbook.insert("Oleg", "+79198745632");
QMultiMap<QString, QString>::iterator it = mapPhbook.find("Gleb");
for (; it != mapPhbook.end() && it.key() == "Gleb"; ++it)
{
    qDebug() << it.value() ;
}


Рис.3. Результат работы программы

    Файлы приложения можно взять здесь.

    На следующем шаге рассмотрим хэши QHash<K,T> и QMultiHash<K,T>.




Предыдущий шаг Содержание Следующий шаг