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