Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
java-style-iterators.qdoc
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4/*!
5 \group java-style-iterators
6 \noautolist
7 \title Java-style Iterators in Qt
8 \ingroup groups
9 \ingroup qt-basic-concepts
10 \brief Java style iterators for Qt's containers.
11
12 \section1 Java-Style Iterators
13
14 For each container class, there are two Java-style iterator data
15 types: one that provides read-only access and one that provides
16 read-write access.
17
18 \note New code should use \l{STL-Style iterators} since these are more efficient
19 and can be used together with Qt's and STL's \l{generic algorithms}.
20
21 \table
22 \header \li Containers \li Read-only iterator
23 \li Read-write iterator
24 \row \li QList<T>, QQueue<T>, QStack<T>, \li QListIterator<T>
25 \li QMutableListIterator<T>
26 \row \li QSet<T> \li QSetIterator<T>
27 \li QMutableSetIterator<T>
28 \row \li QMap<Key, T>, QMultiMap<Key, T> \li QMapIterator<Key, T>
29 \li QMutableMapIterator<Key, T>
30 \row \li QHash<Key, T>, QMultiHash<Key, T> \li QHashIterator<Key, T>
31 \li QMutableHashIterator<Key, T>
32 \endtable
33
34 In this discussion, we will concentrate on QList and QMap. The
35 iterator types for QSet have exactly
36 the same interface as QList's iterators; similarly, the iterator
37 types for QHash have the same interface as QMap's iterators.
38
39 Unlike \l{STL-Style iterators}, Java-style iterators point \e between items
40 rather than directly \e at items. For this reason, they are either pointing
41 to the very beginning of the container (before the first item), at the very
42 end of the container (after the last item), or between two items. The
43 diagram below shows the valid iterator positions as red arrows for a list
44 containing four items:
45
46 \image javaiterators1.svg {Iterator positions between items A, B, C, D}
47
48 Here's a typical loop for iterating through all the elements of a
49 QList<QString> in order:
50
51 \snippet code/doc_src_containers.cpp 1
52
53 It works as follows: The QList to iterate over is passed to the
54 QListIterator constructor. At that point, the iterator is located
55 just in front of the first item in the list (before item "A").
56 Then we call \l{QListIterator::hasNext()}{hasNext()} to
57 check whether there is an item after the iterator. If there is, we
58 call \l{QListIterator::next()}{next()} to jump over that
59 item. The next() function returns the item that it jumps over. For
60 a QList<QString>, that item is of type QString.
61
62 Here's how to iterate backward in a QList:
63
64 \snippet code/doc_src_containers.cpp 2
65
66 The code is symmetric with iterating forward, except that we
67 start by calling \l{QListIterator::toBack()}{toBack()}
68 to move the iterator after the last item in the list.
69
70 The diagram below illustrates the effect of calling
71 \l{QListIterator::next()}{next()} and
72 \l{QListIterator::previous()}{previous()} on an iterator:
73
74 \image javaiterators2.svg Iterating to the next and previous items
75
76 The following table summarizes the QListIterator API:
77
78 \table
79 \header \li Function \li Behavior
80 \row \li \l{QListIterator::toFront()}{toFront()}
81 \li Moves the iterator to the front of the list (before the first item)
82 \row \li \l{QListIterator::toBack()}{toBack()}
83 \li Moves the iterator to the back of the list (after the last item)
84 \row \li \l{QListIterator::hasNext()}{hasNext()}
85 \li Returns \c true if the iterator isn't at the back of the list
86 \row \li \l{QListIterator::next()}{next()}
87 \li Returns the next item and advances the iterator by one position
88 \row \li \l{QListIterator::peekNext()}{peekNext()}
89 \li Returns the next item without moving the iterator
90 \row \li \l{QListIterator::hasPrevious()}{hasPrevious()}
91 \li Returns \c true if the iterator isn't at the front of the list
92 \row \li \l{QListIterator::previous()}{previous()}
93 \li Returns the previous item and moves the iterator back by one position
94 \row \li \l{QListIterator::peekPrevious()}{peekPrevious()}
95 \li Returns the previous item without moving the iterator
96 \endtable
97
98 QListIterator provides no functions to insert or remove items
99 from the list as we iterate. To accomplish this, you must use
100 QMutableListIterator. Here's an example where we remove all
101 odd numbers from a QList<int> using QMutableListIterator:
102
103 \snippet code/doc_src_containers.cpp 3
104
105 The next() call in the loop is made every time. It jumps over the
106 next item in the list. The
107 \l{QMutableListIterator::remove()}{remove()} function removes the
108 last item that we jumped over from the list. The call to
109 \l{QMutableListIterator::remove()}{remove()} does not invalidate
110 the iterator, so it is safe to continue using it. This works just
111 as well when iterating backward:
112
113 \snippet code/doc_src_containers.cpp 4
114
115 If we just want to modify the value of an existing item, we can
116 use \l{QMutableListIterator::setValue()}{setValue()}. In the code
117 below, we replace any value larger than 128 with 128:
118
119 \snippet code/doc_src_containers.cpp 5
120
121 Just like \l{QMutableListIterator::remove()}{remove()},
122 \l{QMutableListIterator::setValue()}{setValue()} operates on the
123 last item that we jumped over. If we iterate forward, this is the
124 item just before the iterator; if we iterate backward, this is
125 the item just after the iterator.
126
127 The \l{QMutableListIterator::next()}{next()} function returns a
128 non-const reference to the item in the list. For simple
129 operations, we don't even need
130 \l{QMutableListIterator::setValue()}{setValue()}:
131
132 \snippet code/doc_src_containers.cpp 6
133
134 As mentioned above QSet's iterator
135 classes have exactly the same API as QList's. We will now turn to
136 QMapIterator, which is somewhat different because it iterates on
137 (key, value) pairs.
138
139 Like QListIterator, QMapIterator provides
140 \l{QMapIterator::toFront()}{toFront()},
141 \l{QMapIterator::toBack()}{toBack()},
142 \l{QMapIterator::hasNext()}{hasNext()},
143 \l{QMapIterator::next()}{next()},
144 \l{QMapIterator::peekNext()}{peekNext()},
145 \l{QMapIterator::hasPrevious()}{hasPrevious()},
146 \l{QMapIterator::previous()}{previous()}, and
147 \l{QMapIterator::peekPrevious()}{peekPrevious()}. The key and
148 value components are extracted by calling \l{QMapIterator::key()}{key()} and \l{QMapIterator::value()}{value()} on
149 the object returned by next(), peekNext(), previous(), or
150 peekPrevious().
151
152 The following example removes all (capital, country) pairs where
153 the capital's name ends with "City":
154
155 \snippet code/doc_src_containers.cpp 7
156
157 QMapIterator also provides a \l{QMapIterator::key()}{key()} and a \l{QMapIterator::value()}{value()} function that
158 operate directly on the iterator and that return the key and
159 value of the last item that the iterator jumped above. For
160 example, the following code copies the contents of a QMap into a
161 QHash:
162
163 \snippet code/doc_src_containers.cpp 8
164
165 If we want to iterate through all the items with the same
166 value, we can use \l{QMapIterator::findNext()}{findNext()}
167 or \l{QMapIterator::findPrevious()}{findPrevious()}.
168 Here's an example where we remove all the items with a particular
169 value:
170
171 \snippet code/doc_src_containers.cpp 9
172
173*/