QMultiMap Class

  • Header: QMultiMap

  • CMake:

    find_package(Qt6 REQUIRED COMPONENTS Core)

    target_link_libraries(mytarget PRIVATE Qt6::Core)

  • qmake: QT += core

  • Group: QMultiMap is part of tools, Implicitly Shared Classes

Detailed Description

QMultiMap<Key, T> is one of Qt's generic container classes. It stores (key, value) pairs and provides fast lookup by key.

QMultiMap and QMultiHash provide very similar functionality. The differences are:

  • QMultiHash provides average faster lookups than QMultiMap. (See Algorithmic Complexity for details.)

  • When iterating over a QMultiHash, the items are arbitrarily ordered. With QMultiMap, the items are always sorted by key.

  • The key type of a QMultiHash must provide operator==() and a global qHash(Key) function. The key type of a QMultiMap must provide operator<() specifying a total order. Since Qt 5.8.1 it is also safe to use a pointer type as key, even if the underlying operator<() does not provide a total order.

Here's an example QMultiMap with QString keys and int values:

 
Sélectionnez
QMultiMap&lt;QString, int&gt; multimap;

To insert a (key, value) pair into the multi map, you can use insert():

 
Sélectionnez
multimap.insert("a", 1);
multimap.insert("b", 3);
multimap.insert("c", 7);
multimap.insert("c", -5);

This inserts the following three (key, value) pairs into the QMultiMap: ("a", 1), ("b", 3), ("c", 7), and ("c", -5); note that duplicate keys are allowed.

To look up a value, use find() or value():

 
Sélectionnez
int num2 = multimap.value("a"); // 1
int num3 = multimap.value("thirteen"); // not found; 0
int num3 = 0;
auto it = multimap.value("b");
if (it != multimap.end()) {
    num3 = it.value();
}

If there is no item with the specified key in the map, these functions return a default-constructed value.

If you want to check whether the map contains a certain key, use contains():

 
Sélectionnez
int timeout = 30;
if (multimap.contains("TIMEOUT"))
    timeout = multimap.value("TIMEOUT");

// better:
auto it = multimap.find("TIMEOUT");
if (it != multimap.end())
    timeout = it.value();

There is also a value() overload that uses its second argument as a default value if there is no item with the specified key:

 
Sélectionnez
int timeout = multimap.value("TIMEOUT", 30);

If you want to navigate through all the (key, value) pairs stored in a QMultiMap, you can use an iterator. QMultiMap provides both Java-style iterators (QMultiMapIterator and QMutableMultiMapIterator) and STL-style iterators (QMultiMap::const_iterator and QMultiMap::iterator). Here's how to iterate over a QMultiMap<QString, int> using a Java-style iterator:

 
Sélectionnez
QMultiMapIterator&lt;QString, int&gt; i(multimap);
while (i.hasNext()) {
    i.next();
    cout &lt;&lt; i.key() &lt;&lt; ": " &lt;&lt; i.value() &lt;&lt; Qt::endl;
}

Here's the same code, but using an STL-style iterator this time:

 
Sélectionnez
auto i = multimap.constBegin();
while (i != multimap.constEnd()) {
    cout &lt;&lt; i.key() &lt;&lt; ": " &lt;&lt; i.value() &lt;&lt; Qt::endl;
    ++i;
}

The items are traversed in ascending key order.

A QMultiMap allows multiple values per key. If you call insert() with a key that already exists in the map, a new (key, value) pair will be inserted. For example:

 
Sélectionnez
multimap.insert("plenty", 100);
multimap.insert("plenty", 2000);
// multimap.size() == 2

If you want to retrieve all the values for a single key, you can use values(const Key &key), which returns a QList<T>:

 
Sélectionnez
QList&lt;int&gt; values = multimap.values("plenty");
for (int i = 0; i &lt; values.size(); ++i)
    cout &lt;&lt; values.at(i) &lt;&lt; Qt::endl;

The items that share the same key are available from most recently to least recently inserted. Another approach is to call find() to get the STL-style iterator for the first item with a key and iterate from there:

 
Sélectionnez
QMultiMap&lt;QString, int&gt;::iterator i = multimap.find("plenty");
while (i != map.end() &amp;&amp; i.key() == "plenty") {
    cout &lt;&lt; i.value() &lt;&lt; Qt::endl;
    ++i;
}

// better:
auto [i, end] = multimap.equal_range("plenty");
while (i != end) {
    cout &lt;&lt; i.value() &lt;&lt; Qt::endl;
    ++i;
}

If you only need to extract the values from a map (not the keys), you can also use foreach:

 
Sélectionnez
QMap&lt;QString, int&gt; multimap;
...
foreach (int value, multimap)
    cout &lt;&lt; value &lt;&lt; Qt::endl;

Items can be removed from the multi map in several ways. One way is to call remove(); this will remove any item with the given key. Another way is to use QMutableMultiMapIterator::remove(). In addition, you can clear the entire map using clear().

It is possible to merge two multi maps by calling unite(), by using operator+(), and by using operator+=(). Example:

 
Sélectionnez
QMultiMap&lt;QString, int&gt; map1, map2, map3;

map1.insert("plenty", 100);
map1.insert("plenty", 2000);
// map1.size() == 2

map2.insert("plenty", 5000);
// map2.size() == 1

map3 = map1 + map2;
// map3.size() == 3

QMultiMap's key and value data types must be assignable data types. This covers most data types you are likely to encounter, but the compiler won't let you, for example, store a QWidget as a value; instead, store a QWidget *. In addition, QMultiMap's key type must provide operator<(). QMap uses it to keep its items sorted, and assumes that two keys x and y are equal if neither x < y nor y < x is true.

Example:

 
Sélectionnez
#ifndef EMPLOYEE_H
#define EMPLOYEE_H

class Employee
{
public:
    Employee() {}
    Employee(const QString &amp;name, QDate dateOfBirth);
    ...

private:
    QString myName;
    QDate myDateOfBirth;
};

inline bool operator&lt;(const Employee &amp;e1, const Employee &amp;e2)
{
    if (e1.name() != e2.name())
        return e1.name() &lt; e2.name();
    return e1.dateOfBirth() &lt; e2.dateOfBirth();
}

#endif // EMPLOYEE_H

In the example, we start by comparing the employees' names. If they're equal, we compare their dates of birth to break the tie.

See Also

Member Type Documentation

 

QMultiMap::ConstIterator

Qt-style synonym for QMultiMap<Key, T>::const_iterator.

QMultiMap::Iterator

Qt-style synonym for QMultiMap<Key, T>::iterator.

[since 5.10] QMultiMap::const_key_value_iterator

The QMultiMap::const_key_value_iterator typedef provides an STL-style iterator for QMultiMap.

QMultiMap::const_key_value_iterator is essentially the same as QMultiMap::const_iterator with the difference that operator*() returns a key/value pair instead of a value.

This typedef was introduced in Qt 5.10.

See Also

[alias] QMultiMap::difference_type

Typedef for ptrdiff_t. Provided for STL compatibility.

[alias] QMultiMap::key_type

Typedef for Key. Provided for STL compatibility.

[since 5.10] QMultiMap::key_value_iterator

The QMultiMap::key_value_iterator typedef provides an STL-style iterator for QMultiMap.

QMultiMap::key_value_iterator is essentially the same as QMultiMap::iterator with the difference that operator*() returns a key/value pair instead of a value.

This typedef was introduced in Qt 5.10.

See Also

[alias] QMultiMap::mapped_type

Typedef for T. Provided for STL compatibility.

[alias] QMultiMap::size_type

Typedef for int. Provided for STL compatibility.

Member Function Documentation

 

[since 6.4] auto QMultiMap::asKeyValueRange() &

[since 6.4] auto QMultiMap::asKeyValueRange() &&

[since 6.4] auto QMultiMap::asKeyValueRange() const &

[since 6.4] auto QMultiMap::asKeyValueRange() const &&

Returns a range object that allows iteration over this multi map as key/value pairs. For instance, this range object can be used in a range-based for loop, in combination with a structured binding declaration:

 
Sélectionnez
QMultiMap&lt;QString, int&gt; map;
map.insert("January", 1);
map.insert("February", 2);
// ...
map.insert("December", 12);

for (auto [key, value] : map.asKeyValueRange()) {
    cout &lt;&lt; key &lt;&lt; ": " &lt;&lt; value &lt;&lt; Qt::endl;
    --value; // convert to JS month indexing
}

Note that both the key and the value obtained this way are references to the ones in the multi map. Specifically, mutating the value will modify the map itself.

This function was introduced in Qt 6.4.

See Also

QMultiMap::QMultiMap()

Constructs an empty multi map.

See Also

See also clear()

[since 5.1] QMultiMap::QMultiMap(std::initializer_list<std::pair<Key, T>> list)

Constructs a multi map with a copy of each of the elements in the initializer list list.

This function was introduced in Qt 5.1.

[explicit, since 6.0] QMultiMap::QMultiMap(const QMap<Key, T> &other)

Constructs a multi map as a copy of other.

This function was introduced in Qt 6.0.

[explicit, since 6.0] QMultiMap::QMultiMap(QMap<Key, T> &&other)

If other is shared, constructs a multi map as a copy of other. Otherwise, constructs a multi map by moving the elements from other.

This function was introduced in Qt 6.0.

[explicit] QMultiMap::QMultiMap(const std::multimap<Key, T> &other)

Constructs a copy of other.

See Also

See also toStdMultiMap()

[explicit] QMultiMap::QMultiMap(std::multimap<Key, T> &&other)

Constructs a multi map by moving from other.

See Also

See also toStdMultiMap()

[default, since 5.2] QMultiMap::QMultiMap(QMultiMap<Key, T> &&other)

Move-constructs a QMultiMap instance, making it point at the same object that other was pointing to.

This function was introduced in Qt 5.2.

[default] QMultiMap::QMultiMap(const QMultiMap<Key, T> &other)

Constructs a copy of other.

This operation occurs in constant time, because QMultiMap is implicitly shared. This makes returning a QMultiMap from a function very fast. If a shared instance is modified, it will be copied (copy-on-write), and this takes linear time.

See Also

See also operator=()

[default] QMultiMap::~QMultiMap()

Destroys the multi map. References to the values in the multi map, and all iterators over this multi map, become invalid.

QMultiMap::iterator QMultiMap::begin()

Returns an STL-style iterator pointing to the first item in the multi map.

See Al