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:
QMultiMap&
lt;QString, int
&
gt; multimap;
To insert a (key, value) pair into the multi map, you can use insert():
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():
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():
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:
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:
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:
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:
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>:
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:
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:
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:
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:
#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▲
See also QMultiMapIterator, QMutableMultiMapIterator, QMultiHash
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▲
See also QKeyValueIterator
[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▲
See also QKeyValueIterator
[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:
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▲
See also QKeyValueIterator
QMultiMap::QMultiMap()▲
[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)▲
[explicit] QMultiMap::QMultiMap(std::multimap<Key, T> &&other)▲
[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.