文章目录
- 一、QList类介绍
- 二、QList类中的函数
- 1.构造函数
- 2.插入元素的函数
- 3.删除元素的函数
- 3.1 removeAt函数--从 QList 容器中移除指定索引 i 处的元素
- 3.2 removeFirst函数--从 QList 容器中移除第一个元素
- 3.3 removeLast函数--从 QList 容器中移除最后一个元素
- 3.4 removeOne函数--从 QList 容器中移除第一次出现的指定值 value
- 3.5 removeAll函数--从 QList 容器中移除所有与给定值 value 匹配的元素,并返回被移除元素的数量
- 3.6 takeAt函数--从 `QList` 容器中移除指定索引 `i` 处的元素,并返回被移除的元素的值
- 3.7 takeFirst函数--从 QList 容器中移除第一个元素,并返回被移除元素的值
- 3.8 takeLast函数--从 QList 容器中移除最后一个元素,并返回被移除元素的值
- 3.9 clear函数--清空 QList 容器中的所有元素
- 3.10 pop_back函数--从 QList 容器中移除最后一个元素
- 3.11 pop_front函数--从 QList 容器中移除第一个元素
- 4.访问元素的函数
- 5.查找元素的函数
- 6.大小与空检查函数
- 7.其他操作函数--替换、交换、移动、预留空间
- 8.转换成其他容器类
- 9.迭代器相关函数
- 10.QList支持的操作符函数
一、QList类介绍
QList是Qt框架中的一种泛型容器类,虽然是以数组列表(array-list)的形式实现的,但是在其前或后添加数据非常块。提供快速的基于索引的访问、插入和删除操作。使用时需要如下设置:
Header:
#include <QList>
qmake:
QT += core
QList的一些特性如下:
-
内存布局:QList内部可能以数组或指针数组的形式表示,具体取决于元素类型的大小和是否可移动。“是否可移动”通常指的是元素类型是否支持移动构造函数或移动赋值运算符。
-
内存分配:QList在内部数组的两端预分配额外空间,以允许列表两端的快速增长。
-
类型要求:QList的值类型必须是可赋值的
-
效率:为了效率,QList成员函数在使用前不验证输入,因此调用者应确保参数有效。
-
兼容性:QList不保证C兼容的数组布局
-
扩展功能:对于特定类型(如QByteArray和QString),QList提供了额外的成员函数。
二、QList类中的函数
1.构造函数
QList的构造函数提供了多种初始化QList
的方式,包括从迭代器范围、初始化列表、移动构造、复制构造和默认构造。
-
模板构造函数:
//InputIterator的值类型必须可以转换为QList的模板参数T template <typename InputIterator> QList(InputIterator first, InputIterator last)
使用迭代器范围来构造
QList
。允许从任何可迭代的容器或数组中初始化QList
。示例:
std::vector<int> vec = {1, 2, 3, 4, 5}; QList<int> listFromVec(vec.begin(), vec.end());
-
初始化列表构造函数
QList(std::initializer_list<T> args)
这个构造函数使用C++11标准引入的初始化列表来构造
QList
。它接受一个std::initializer_list<T>
类型的参数args
,其中T
是QList
的元素类型。示例:
QList<int> listFromInitList = {1, 2, 3, 4, 5};
-
移动构造函数
QList(QList<T> &&other)
移动构造函数会将
other
所指向的对象的所有权转移给新创建的QList
对象,而不是复制对象。使用移动构造函数来避免复制开销。示例:
QList<int> tempList = {1, 2, 3, 4, 5}; QList<int> movedList = std::move(tempList); // Move semantics
-
复制构造函数
QList(const QList<T> &other)
使用复制构造函数来创建
QList
的深拷贝。由于QList
的隐式共享特性,这个操作通常是常数时间的。隐式共享的理解:
隐式共享是对象的管理办法。一个对象被隐式共享,只是传递该对象的一个指针给使用者,而不实际复制对象数据,只有在使用者修改数据时,才实质复制共享对象给使用者。
- 共享数据:当复制一个
QList
对象时,新对象不会立即复制原始对象的所有数据。相反,两个对象会共享相同的内部数据(元素数组和内存分配)。它们共享一个指向相同数据的指针。 - 节省内存:由于两个
QList
对象共享相同的数据,因此复制操作非常快速,并且不会消耗额外的内存,直到需要修改列表之一。 - 延迟复制:当对共享的
QList
对象进行修改时(例如添加或删除元素),QList
会首先复制共享的数据到一个新的内存区域,然后对新内存区域进行修改。这样,只有当实际需要修改时才会创建数据的副本。 - 独立操作:一旦数据被复制,两个
QList
对象就会独立操作它们各自的数据副本,后续的修改不会影响另一个对象。
示例:
QList<int> list1; list1.append(1); list1.append(2); QList<int> list2 = list1; // 快速复制,共享数据 list2.append(3); // 此时 list2 触发数据复制,不再与 list1 共享数据
通过赋值操作创建了
list2
,此时list2
与list1
共享相同的数据,复制操作很快。当list2
添加新元素时,触发了数据的复制,list2
现在有自己的数据副本,与list1
不再共享。示例:
QList<int> originalList = {1, 2, 3, 4, 5}; QList<int> copiedList = originalList; // Copy constructor
- 共享数据:当复制一个
-
默认构造函数
QList()
创建一个空的
QList
对象示例:
QList<int> emptyList; // Default constructor
2.插入元素的函数
2.1 append函数–在 QList容器的末尾添加元素
-
append函数:在末尾插入元素
void QList::append(const T &value)
-
函数作用:
用于在
QList
容器的末尾添加一个元素,等价于list.insert(size(), value)
-
示例:
QList<QString> list; list.append("one"); list.append("two"); list.append("three"); // 此时 list 的内容为:["one", "two", "three"]
-
注意事项:
- 对于非共享的
QList
(即没有其他QList
实例共享其数据),添加元素(如使用append
)通常是快速的,因为QList
会预先分配额外的内存,以便快速扩展。 - 如果
QList
是共享的,添加元素时可能会触发数据复制,这可能会稍微慢一些,因为需要先复制数据再进行添加操作。
- 对于非共享的
-
-
append函数:在末尾插入列表
void QList::append(const QList<T> &value)
-
函数说明:
这是一个重载函数。用于将
value
列表中的所有项追加到当前列表中的末尾。 -
示例:
QList<int> list1; list1.append(1); list1.append(2); QList<int> list2; list2.append(3); list2.append(4); list1.append(list2); // 现在 list1 包含 [1, 2, 3, 4]
-
使用场景:
此函数的使用场景是当你想要合并两个列表时,例如,将一个列表中的所有元素添加到另一个列表的末尾。
-
2.2 prepend函数–在 QList容器的头部添加元素
void QList::prepend(const T &value)
-
函数说明:
用于在
QList
容器的头部添加元素,等价于list.insert(0, value)
-
示例:
QList<QString> list; list.prepend("one"); list.prepend("two"); list.prepend("three"); // list: ["three", "two", "one"]
-
注意事项:
- 对于非共享的
QList
(即没有其他QList
实例共享其数据),这个操作是非常高效的。因为QList
在其内部缓冲区的两侧预先分配了额外的空间,以便在列表的两端快速增长。 - 如果
QList
是共享的(即有其他QList
实例共享相同的数据),则在prepend
操作中可能会触发数据复制,以确保当前列表拥有独立的数据副本。这可能会稍微降低性能,因为需要先复制数据再进行插入操作。
- 对于非共享的
2.3 insert函数–在 QList 容器的指定索引位置插入元素
-
insert函数:特定索引位置
void QList::insert(int i, const T &value)
-
函数说明:
用于在
QList
容器的指定索引位置插入元素- 如果
i == 0
,则等价于prepend函数 - 如果
i == size()
,则等价于append函数
- 如果
-
示例:
QList<QString> list; //QList中的operator<<()操作符也可以用于追加元素 list << "alpha" << "beta" << "delta"; list.insert(2, "gamma"); // list: ["alpha", "beta", "gamma", "delta"]
-
注意事项:
insert
操作可能会导致列表中的后续元素向后移动,以便为新插入的元素腾出空间。因此,insert
操作的时间复杂度为O(n)
,其中n
是列表中元素的数量。在最坏的情况下,可能需要移动所有现有元素。- 如果
QList
是共享的,insert
操作可能会触发数据的复制,以确保当前列表拥有独立的数据副本。这可能会稍微降低性能,因为需要先复制数据再进行插入操作。
-
-
insert函数:迭代器指向的项
QList::iterator QList::insert(QList::iterator before, const T &value)
-
函数说明:
这是一个重载函数。在迭代器
before
指向的项前面插入值。返回一个指向插入项的迭代器。 -
示例:
QList<int> list; list << 1 << 2 << 4; // 初始化列表 QList<int>::iterator it = list.begin() + 2; // 获取指向元素 '4' 的迭代器 list.insert(it, 3); // 在索引 2 的位置前插入元素 '3' // 现在 list 是 [1, 2, 3, 4]
-
注意事项:
传递给函数的迭代器在调用后将无效;应该使用返回的迭代器。
这是因为插入操作可能会改变列表中元素的布局或导致迭代器所指向的位置发生变化。因此,应使用函数返回的迭代器来引用新插入的元素。
需要注意迭代器的有效期和在容器修改后迭代器的失效问题
-
2.4 push_back函数–在 QList容器的末尾添加元素
void QList::push_back(const T &value)
-
函数说明:
用于在在 QList容器的末尾添加元素。等价于
append(value)
。push_back
函数的存在是为了用于与C++标准模板库(STL)保持兼容性
2.5 push_front函数–在 QList容器的头部添加元素
void QList::push_front(const T &value)
-
函数说明:
用于在QList容器的头部添加元素。等价于
prepend(value)
函数。与push_back
类似,push_front
也是为了与STL的接口保持一致。
3.删除元素的函数
3.1 removeAt函数–从 QList 容器中移除指定索引 i 处的元素
void QList::removeAt(int i)
-
函数说明:
用于从
QList
容器中移除指定索引i
处的元素。调用此函数时,必须确保
i
是一个有效的索引,即它在列表的有效范围内(0 <= i < size()
)。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; list.removeAt(2); // 移除索引为 2 的元素,即 '3' // 现在 list 是 [1, 2, 4, 5]
-
注意事项:
-
如果索引
i
超出了有效范围(小于 0 或大于或等于size()
),则removeAt
函数将不会执行任何操作,并且可能触发断言以指示错误。如:
QList::removeAt(): Index out of range.
-
此函数不返回任何值,它直接在列表上进行原地修改(in-place modification)。
-
removeAt
操作可能会导致列表中的后续元素向前移动,以填补被移除元素的位置。因此,removeAt
的时间复杂度为O(n)
-
3.2 removeFirst函数–从 QList 容器中移除第一个元素
void QList::removeFirst()
-
函数说明:
用于移除
QList
容器中的第一个元素。等价于removeAt(0)
-
示例:
QList<int> list = {1, 2, 3, 4, 5}; if (!list.isEmpty()) { list.removeFirst(); // 移除第一个元素,即 '1' // 现在 list 是 [2, 3, 4, 5] }
-
注意事项:
在调用
removeFirst
之前,需要确保列表不为空。如果列表为空,调用removeFirst
将不执行任何操作,并且可能会触发断言错误。可以通过先调用isEmpty()
来检查列表是否为空,从而避免在空列表上调用removeFirst
导致的问题。
3.3 removeLast函数–从 QList 容器中移除最后一个元素
void QList::removeLast()
-
函数说明:
用于从
QList
容器中移除最后一个元素,等价于removeAt(size() - 1)
-
示例:
QList<int> list = {1, 2, 3, 4, 5}; if (!list.isEmpty()) { list.removeLast(); // 移除最后一个元素,即 '5' // 现在 list 是 [1, 2, 3, 4] }
-
注意事项:
在调用
removeLast
之前,需要确保列表不为空。如果列表为空,调用removeLast
将不执行任何操作,并且可能会触发断言错误。可以通过先调用isEmpty()
来检查列表是否为空,从而避免在空列表上调用removeLast
导致的问题。
3.4 removeOne函数–从 QList 容器中移除第一次出现的指定值 value
bool QList::removeOne(const T &value)
-
函数说明:
用于从
QList
容器中移除第一次出现的指定值value
。如果找到该值并成功移除,则函数返回true
;如果列表中没有该值,则不执行任何操作,并返回false
。 -
示例:
QList<QString> list; list << "sun" << "cloud" << "sun" << "rain"; bool isRemoved = list.removeOne("sun"); // 尝试移除列表中的第一个 "sun" // list: ["cloud", "sun", "rain"] if (isRemoved) { qDebug() << "One 'sun' was removed."; } else { qDebug() << "There was no 'sun' to remove."; }
-
注意事项:
removeOne
函数只移除第一个匹配的元素,不会影响列表中其他相同的元素。- 此函数要求类型
T
重载了operator==()
,以便能够比较列表中的元素与给定的值value
是否相等。
3.5 removeAll函数–从 QList 容器中移除所有与给定值 value 匹配的元素,并返回被移除元素的数量
int QList::removeAll(const T &value)
-
函数说明:
用于从
QList
容器中移除所有与给定值value
匹配的元素,并返回被移除元素的数量。 -
示例:
QList<QString> list; list << "sun" << "cloud" << "sun" << "rain"; list.removeAll("sun"); // list: ["cloud", "rain"]
-
注意事项:
removeAll
函数与removeOne
函数不同,removeOne
只移除第一个匹配的元素,而removeAll
移除所有匹配的元素。- 此函数要求类型
T
必须重载了operator==()
,以便能够比较列表中的元素与给定的值value
是否相等。
3.6 takeAt函数–从 QList
容器中移除指定索引 i
处的元素,并返回被移除的元素的值
T QList::takeAt(int i)
-
函数说明:
用于从
QList
容器中移除指定索引i
处的元素,并返回被移除的元素的值。调用此函数时,必须确保i
是一个有效的索引,即它在列表的有效范围内(即,0 <= i < size()
)。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; int removedValue = list.takeAt(2); // 移除并获取索引为 2 的元素,即 '3' // 现在 list 是 [1, 2, 4, 5] // removedValue 是 3
-
注意事项:
- 如果移除元素后不需要其值,使用
removeAt()
可能更有效率,因为takeAt
需要处理返回值,这可能涉及额外的开销。然而,如果需要使用被移除的元素的值,takeAt
提供了一个方便的方式来同时完成移除和获取操作。 takeAt
操作可能会导致列表中的后续元素向前移动,以填补被移除元素的位置。因此,takeAt
的时间复杂度为 `O(n)
- 如果移除元素后不需要其值,使用
3.7 takeFirst函数–从 QList 容器中移除第一个元素,并返回被移除元素的值
T QList::takeFirst()
-
函数说明:
用于从
QList
容器中移除第一个元素,并返回被移除元素的值。等价于takeAt(0)
-
示例:
QList<int> list = {1, 2, 3, 4, 5}; if (!list.isEmpty()) { int firstValue = list.takeFirst(); // 移除并获取第一个元素,即 1 // 现在 list 是 [2, 3, 4, 5] // firstValue 是 1 }
-
注意事项:
- 调用
takeFirst
之前,应确保列表不为空。如果列表可能为空,应先调用isEmpty()
函数进行检查,以避免调用takeFirst
时出现错误 - 如果不需要使用被移除元素的返回值,使用
removeFirst()
可能更有效率
- 调用
3.8 takeLast函数–从 QList 容器中移除最后一个元素,并返回被移除元素的值
T QList::takeLast()
-
函数说明:
用于从
QList
容器中移除最后一个元素,并返回被移除元素的值。等价于takeAt(size() - 1)
-
示例:
QList<int> list = {1, 2, 3, 4, 5}; if (!list.isEmpty()) { int lastValue = list.takeLast(); // 移除并获取最后一个元素,即 5 // 现在 list 是 [1, 2, 3, 4] // lastValue 是 5 }
-
注意事项:
- 在调用
takeLast
之前,需要确保列表不为空。如果列表可能为空,应先调用isEmpty()
函数进行检查,以避免调用takeLast
时出现错误。 - 如果不需要使用被移除元素的返回值,使用
removeLast()
可能更有效率
- 在调用
3.9 clear函数–清空 QList 容器中的所有元素
void QList::clear()
-
函数说明:
用于清空
QList
容器中的所有元素。调用此函数后,列表将变为空,不再包含任何元素。这个函数不返回任何值,它只对列表本身进行修改。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; list.clear(); // 清空列表 // 现在 list 是空的
-
注意事项:
clear
操作通常需要常数时间O(1)
,因为它只涉及重置列表的内部状态,而不需要逐个移除列表中的元素。- 如果列表是通过隐式共享机制复制的,
clear
操作将只影响当前列表实例,而不会影响其他共享同一数据的列表实例。
3.10 pop_back函数–从 QList 容器中移除最后一个元素
void QList::pop_back()
-
函数说明:
用于从 QList 容器中移除最后一个元素,等价于
removeLast()
函数。pop_back
函数是为了与STL容器的接口保持一致
3.11 pop_front函数–从 QList 容器中移除第一个元素
void QList::pop_front()
-
函数说明:
用于从 QList 容器中移除第一个元素,等价于
removeFirst()
函数。与pop_back
类似,pop_front
也是为了与STL的接口保持一致。
4.访问元素的函数
4.1 at函数–访问 QList 容器中指定索引 i 处的元素,返回对该元素的常量引用
const T &QList::at(int i) const
-
函数说明:
用于访问
QList
容器中指定索引i
处的元素,并返回对该元素的引用。调用此函数时,必须确保i
是一个有效的索引,即它在列表的有效范围内(i.e., 0 <= i < size()) -
示例:
QList<int> list = {1, 2, 3, 4, 5}; int index = 2; int value = list.at(index); // 获取索引为 2 的元素,即 '3' // value 是 3
-
注意事项:
-
at
函数提供常数时间复杂度O(1)
的访问,因为它直接通过索引访问元素,不需要搜索或其他操作。 -
如果索引 i 超出有效范围,则会发生如下错误
最好在使用
at
函数之前,通过size
成员函数或迭代器来验证索引是否在有效范围内。 -
at
函数返回的是一个对元素的常量引用,这意味着可以通过这个引用来读取元素的值,但在使用at
时不能直接通过返回值修改列表中的元素。如果需要修改元素,应使用operator[]
或直接通过迭代器访问。
-
4.2 value函数–访问 QList 容器中指定索引 i 处的元素的值
-
value函数:未提供越界的默认值
T QList::value(int i) const
-
函数说明:
用于访问
QList
容器中指定索引i
处的元素的值。如果索引i
超出范围,函数使用类型T
的默认构造函数创建的对象实例。如果确定索引将在范围内,可以使用at()
代替,后者稍微快一些。使用类型
T
的默认构造函数创建的对象实例:对于内置类型,如int
,这通常意味着返回0
。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; int index = 5; // 索引超出范围 int value = list.value(index); // 返回默认值 0,因为索引 5 超出列表范围 // value 是 0
-
注意事项:
如果可以保证索引始终有效,使用
at
或operator[]
可以提供更好的性能。
-
-
value函数:提供越界的默认值
T QList::value(int i, const T &defaultValue) const
-
函数说明:
当索引
i
在列表的有效范围内时,此函数的行为与未重载的value(int i)
函数相同,即返回列表中索引i
处的元素值。如果索引i
超出列表的当前大小,即不在有效范围内,返回提供的defaultValue
。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; int index = 10; // 索引超出范围 int defaultValue = -1; // 指定默认值 int value = list.value(index, defaultValue); // 返回 defaultValue,因为索引 10 超出范围 // value 是 -1
-
4.3 operator[]函数–通过下标访问 QList 容器中的元素,返回该元素的引用
T &QList::operator[](int i)
-
函数说明:
QList::operator[]
是QList
类的一个成员函数,它重载了中括号[]
运算符,以便通过下标访问列表中的元素。与at()
函数不同,operator[]
返回的是元素的引用,这意味着可以通过这个引用来修改列表中的元素。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; int index = 2; list[index] = 10; // 将索引为 2 的元素修改为 '10' // 现在 list 是 [1, 2, 10, 4, 5]
-
注意事项:
- 使用
operator[]
可以方便地通过下标修改列表中的元素,适用于需要直接访问和修改列表内容的场景。如果不需要修改列表,应该使用at()
函数。 operator[]
函数的运行时间通常是常数时间O(1)
,因为它直接通过索引访问元素。然而,如果因为共享而触发了副本操作,这将增加额外的时间开销。- 如果
QList
是共享的(即有其他QList
实例共享相同的数据),调用operator[]
将触发一个副本操作,使得当前列表拥有独立的数据副本,以确保修改不会影响其他共享该数据的列表实例。
- 使用
const T &QList::operator[](int i) const
-
函数说明:
这个重载版本返回的是元素的常量引用。不能修改列表内容,适合只读访问。
4.4 first函数–获取 QList 容器中第一个元素的引用
T &QList::first()
-
函数说明:
用于获取
QList
容器中第一个元素的引用。调用此函数时,必须确保列表不为空 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; if (!list.isEmpty()) { int firstItem = list.first(); // 获取第一个元素,即 '1' // firstItem 是 1 }
-
注意事项:
- 如果需要处理可能为空的列表,应在调用
first
之前使用isEmpty()
函数进行检查,以避免运行时错误 - 如果只需要读取第一个元素的值,可以使用
constFirst()
函数。如果需要修改列表的第一个元素,可以使用first
函数。
- 如果需要处理可能为空的列表,应在调用
const T &QList::first() const
const T &QList::constFirst() const
-
函数说明:
用于获取
QList
容器中第一个元素的常量引用。这意味着你可以读取这个元素的值,但不能修改它。适用于只读场景或在常量列表上操作。
4.5 front函数–获取 QList 容器中第一个元素的引用
T &QList::front()
const T &QList::front() const
-
函数说明:
用于访问列表的第一个元素。等价于
first()
函数。提供此函数是为了与STL容器的接口保持一致
4.6 last函数–获取 QList 容器中最后一个元素的引用
T &QList::last()
-
函数说明:
用于获取
QList
容器中最后一个元素的引用。这意味着你可以读取这个元素的值,并且可以修改它。调用last
之前,需要确保列表不为空。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; if (!list.isEmpty()) { int lastItem = list.last(); // 获取最后一个元素,即 5 // lastItem 是 5 }
-
注意事项:
- 如果列表可能为空,应先调用
isEmpty()
函数进行检查 - 如果只需要读取最后一个元素的值,可以使用
constLast()
函数。如果需要修改列表的最后一个元素,可以使用last()
函数。
- 如果列表可能为空,应先调用
const T &QList::last() const
const T &QList::constLast() const
-
函数说明
用于获取
QList
容器中第一个元素的常量引用。这意味着你可以读取这个元素的值,但不能修改它。适用于只读场景或在常量列表上操作。
4.7 back函数–获取 QList 容器中最后一个元素的引用
T &QList::back()
const T &QList::back() const
-
函数说明:
back
函数用于获取对QList
容器最后一个元素的引用。等价与last()
函数。提供此函数是为了与STL容器的接口保持一致。
4.8 mid函数–从QList对象中提取一个子列表
QList<T> QList::mid(int pos, int length = -1) const
-
函数说明:
用于从
QList
对象中提取一个子列表,子列表的起始位置由pos
指定。如果length
为-1(默认值),则从pos
开始包括所有元素;否则包括length
个元素(或者如果有不足length
个剩余元素,则包括所有剩余元素)。 -
示例:
QList<int> list = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // 获取从索引3开始的子列表,包括所有剩余元素 QList<int> subList1 = list.mid(3); //SubList1: 3 4 5 6 7 8 9 // 获取从索引3开始的子列表,长度为4 QList<int> subList2 = list.mid(3, 4); //SubList2: 3 4 5 6
-
注意事项:
mid
函数通常是一个高效的操作,因为它可能只需要复制指定范围内的元素引用,而不是复制整个列表。
5.查找元素的函数
5.1 contains函数–检查 QList 容器中是否存在给定值 value 的至少一个匹配项
bool QList::contains(const T &value) const
-
函数说明:
用于检查
QList
容器中是否存在给定值value
的至少一个匹配项。如果列表中至少存在一个元素与value
相等,则函数返回true
。如果没有找到匹配项,则返回false
。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; bool containsThree = list.contains(3); // 返回 true bool containsSix = list.contains(6); // 返回 false
-
注意事项:
- 此函数要求元素类型
T
必须重载了operator==()
,以便能够比较元素是否相等。因为contains
需要遍历列表并比较每个元素与给定值。 - 使用
contains
函数可以方便地检查列表中是否存在某个元素,而不需要手动遍历列表。
- 此函数要求元素类型
5.2 indexof函数–查找特定值 value 在 QList 容器中的索引位置并返回
int QList::indexOf(const T &value, int from = 0) const
-
函数说明:
用于查找特定值
value
在QList
容器中的索引位置。搜索从指定的索引位置from
开始,如果不提供from
参数,默认从列表开头(索引 0)开始。如果在列表中找到该值,函数返回它首次出现的索引;如果没有找到,返回-1
。 -
示例:
QList<QString> list; list << "A" << "B" << "C" << "B" << "A"; list.indexOf("B"); // 返回 1 list.indexOf("B", 1); // 返回 1 list.indexOf("B", 2); // 返回 3 list.indexOf("X"); // 返回 -1
-
注意事项:
- 此函数要求元素类型
T
必须重载了operator==()
,以便能够比较元素是否相等。 indexOf
函数在列表中从指定的from
索引开始线性搜索,直到找到匹配的元素或到达列表末尾。
- 此函数要求元素类型
5.3 lastIndexOf函数–在 QList 容器中查找特定值 value 的索引位置
int QList::lastIndexOf(const T &value, int from = -1) const
-
函数说明:
用于在
QList
容器中查找特定值value
的索引位置,不过这次是从后向前搜索。搜索从指定的索引位置from
开始,如果不提供from
参数,默认从列表末尾(索引-1
)开始。如果在列表中找到该值,函数返回它最后一次出现的索引;如果没有找到,返回-1
。 -
示例:
QList<QString> list; list << "A" << "B" << "C" << "B" << "A"; list.lastIndexOf("B"); // 返回 3 list.lastIndexOf("B", 3); // 返回 3 list.lastIndexOf("B", 2); // 返回 1 list.lastIndexOf("X"); // 返回 -1
-
注意事项:
- 此函数要求元素类型
T
必须重载了operator==()
lastIndexOf
函数在列表中从指定的from
索引开始反向搜索,直到找到匹配的元素或到达列表开头。
- 此函数要求元素类型
5.4 startsWith函数–检查 QList 对象的第一个元素是否与给定的值 value 相等
bool QList::startsWith(const T &value) const
-
函数说明:
用于检查
QList
对象的第一个元素是否与给定的值value
相等。如果相等,则返回true
;否则返回false
。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; // 检查列表的第一个元素是否为特定的值 if (list.startsWith(1)) { std::cout << "The list starts with the value 1." << std::endl; } else { std::cout << "The list does not start with the value 1." << std::endl; }
-
注意事项:
- 这是一个常量成员函数,意味着它不会修改
QList
对象的状态。
- 这是一个常量成员函数,意味着它不会修改
5.5 endsWith函数–检查QList对象的最后一个元素是否与给定的值value相等
bool QList::endsWith(const T &value) const
-
函数说明:
用来检查
QList
对象的最后一个元素是否与给定的值value
相等。如果相等则返回true
;否则返回false
。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; // 检查列表的最后一个元素是否为特定的值 if (list.endsWith(5)) { std::cout << "The list ends with the value 5." << std::endl; } else { std::cout << "The list does not end with the value 5." << std::endl; }
6.大小与空检查函数
这三个函数的时间复杂度均为
O(1)
6.1 count函数–返回 QList 容器中元素的数量
int QList::count() const
-
函数说明:
用于返回
QList
容器中元素的数量。等价于size()
函数。两者可以互换使用,没有功能上的区别。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; int itemCount = list.count(); // 获取元素数量 // itemCount 是 5
int QList::count(const T &value) const
-
函数说明:
用于统计并返回
value
在QList
中出现的次数 -
示例:
QList<int> list = {1, 2, 2, 2, 5}; int itemCount = list.count(2); // 获取元素数量 // itemCount 是 3
-
注意事项:
-
函数要求值类型具有 operator==() 的实现,即必须能够比较两个
T
类型对象是否相等。 -
函数是
const
成员函数,意味着它不会修改QList
对象的状态。 -
对于基本数据类型(如
int
、double
等)和大多数 Qt 类型,==
操作符默认是可用的。如果使用自定义类型,你需要确保为该类型重载了==
操作符。
-
6.2 size函数–返回 QList 容器中元素的数量
int QList::size() const
-
函数说明:
用于返回
QList
容器中元素的数量。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; int listSize = list.size(); // 获取列表大小 // listSize 是 5
6.3 length函数–获取列表中元素的数量
int QList::length() const
-
函数说明:
用于获取列表中元素的数量。等价于
count()
函数
6.4 isEmpty函数–检查 QList 容器是否为空
bool QList::isEmpty() const
-
函数说明:
用于检查
QList
容器是否为空,即列表中是否没有任何元素。当列表中没有元素时,此函数返回true
;如果列表中至少有一个元素,函数返回false
。 -
示例:
QList<int> list; if (list.isEmpty()) { qDebug() << "The list is empty."; } else { qDebug() << "The list is not empty."; }
-
使用场景:
isEmpty
函数通常用于在执行操作之前验证列表是否包含元素
7.其他操作函数–替换、交换、移动、预留空间
7.1 replace函数–将 QList 中指定索引 i 处的元素替换为新的值value
void QList::replace(int i, const T &value)
-
函数说明:
用于将
QList
中指定索引i
处的元素替换为新的值value
。需要确保提供的索引i
是有效的。这意味着索引i
必须在列表的当前大小范围内(即,0 <= i < size()
)。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; // 替换索引为2的元素(即,元素3) list.replace(2, 30); //交换后:1 2 30 4 5
7.2 swap函数–交换两个QList
对象的元素
void QList::swap(QList<T> &other)
-
函数说明:
用于交换两个
QList
对象的元素。这意味着函数执行后,两个列表将拥有对方的元素。 -
示例:
QList<int> list1 = {1, 2, 3}; QList<int> list2 = {4, 5, 6}; // 交换两个列表的内容 list1.swap(list2); //List1 contains: 4 5 6 //List2 contains: 1 2 3
-
注意事项:
- 这个操作的效率高,因为它通常只涉及交换内部指针或引用计数等少量数据,而不是交换实际的元素数据。在Qt中,由于
QList
的隐式共享机制,交换操作通常只需要交换内部数据的引用,因此非常快速。 - 由于交换操作不涉及资源分配或复杂的状态转换,它被认为是一个不会失败的操作。这意味着
swap
函数总是能够成功执行,不会抛出异常或返回错误。
- 这个操作的效率高,因为它通常只涉及交换内部指针或引用计数等少量数据,而不是交换实际的元素数据。在Qt中,由于
7.3 swapItemsAt函数–交换QList中两个指定索引位置的元素
void QList::swapItemsAt(int i, int j)
-
函数说明:
swapItemsAt
函数用于交换QList
中两个指定索引位置的元素。这是一个就地操作,不涉及元素的移除和重新插入,因此通常比先移除再插入更高效。 -
示例:
QList<QString> list; list << "A" << "B" << "C" << "D" << "E" << "F"; list.swapItemsAt(1, 4); // 列表:["A", "E", "C", "D", "B", "F"]
-
注意事项:
- 交换操作通常是非常快速的,因为它只涉及几个指针或引用的交换,不需要复制或移动元素数据。
swapItemsAt
函数从Qt 5.13版本开始提供
7.4 move函数–将 QList 中一个位置的元素移动到另一个位置
void QList::move(int from, int to)
-
函数说明:
将位于索引位置
from
的项移动到索引位置to
。这不会改变元素的值,只是改变其在列表中的位置。等价于insert(to, takeAt(from))
。 -
示例:
QList<QString> list; list << "A" << "B" << "C" << "D" << "E" << "F"; list.move(1, 4); // 列表:["A", "C", "D", "E", "B", "F"]
-
注意事项:
- 如果
to
大于from
,剪切的元素将插入到to
之后的所有元素之前;如果to
小于from
,剪切的元素将插入到to
之前。 move
操作通常比删除一个元素然后插入一个新元素更高效,因为它避免了复制整个列表的开销。
- 如果
7.5 reserve函数–预留alloc
个元素的空间
void QList::reserve(int alloc)
-
函数说明:
用于为
QList
预留足够的内存空间以存储指定数量的元素。这有助于提高性能,尤其是在你知道将要添加大量元素的情况下。 -
示例:
QList<int> list; // 预测将添加100个元素,预先分配空间 list.reserve(100);
-
注意事项:
- 使用场景:当你预计会向
QList
中添加大量元素时,可以在添加之前调用reserve
,以优化性能。例如,在读取大量数据并将其添加到列表中之前,可以先调用reserve
。 - 性能优化:通过预留空间,可以减少在添加元素时可能发生的多次内存重新分配,从而提高性能。这对于大型数据集或在循环中频繁添加元素的场景特别有用。
- 如果指定的
alloc
值小于列表当前的元素数量,reserve
函数将不执行任何操作,因为当前的内存分配已经足够存储现有元素。
- 使用场景:当你预计会向
8.转换成其他容器类
8.1 toSet函数–将QList对象转换为QSet对象
QSet<T> QList::toSet() const
-
函数说明:
toSet
函数将QList
对象转换为QSet
对象。由于QSet
是一个不允许重复元素的集合,转换后的QSet
可能包含比原始列表更少的元素,因为所有重复项都会被去除。此函数适用于需要去除列表中的重复项并创建一个唯一元素集合的场景。
-
示例:
QStringList list; list << "Julia" << "Mike" << "Mike" << "Julia" << "Julia"; QSet<QString> set = list.toSet(); set.contains("Julia"); // 返回 true set.contains("Mike"); // 返回 true set.size(); // 返回 2
8.2 toVector函数–将QList对象转换为QVector对象
QVector<T> QList::toVector() const
-
函数说明:
toVector
函数将QList
对象转换为QVector
对象。转换后的QVector
包含与QList
相同的元素序列。 -
示例:
QStringList list; list << "Sven" << "Kim" << "Ola"; QVector<QString> vect = list.toVector(); // vect: ["Sven", "Kim", "Ola"]
-
注意事项:
- 此函数适用于需要将列表数据转换为向量数据结构的场景。
QVector
提供了不同于QList
的特性,例如可能更好的缓存局部性和固定内存大小。 - 从Qt 5.14开始,推荐使用范围构造函数来直接从列表创建
QVector
,这可能比使用toVector
方法更直接和高效。
- 此函数适用于需要将列表数据转换为向量数据结构的场景。
8.3 toStdList函数
std::list<T> QList::toStdList() const
-
函数说明:
toStdList
函数将QList
对象转换为C++标准模板库中的std::list
对象。转换后的std::list
包含与QList
相同的元素序列。 -
示例:
QList<double> list; list << 1.2 << 0.5 << 3.14; std::list<double> stdlist = list.toStdList();
-
注意事项:
- 此函数用于在Qt容器和标准库容器之间迁移数据。
std::list
是一个链表,提供不同于QList
的特性,例如在列表中间插入和删除元素的高效操作。 - 从Qt 5.14开始,推荐使用范围构造函数来直接从
QList
创建std::list
,这可能比使用toStdList
方法更直接和高效。
- 此函数用于在Qt容器和标准库容器之间迁移数据。
9.迭代器相关函数
9.1 begin、cbegin、rbegin、crbegin、constBegin函数
QList::iterator QList::begin()
-
函数说明:
begin
函数提供了对QList
容器开始位置的访问,返回的迭代器可以用于遍历列表中的元素。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; // 使用begin()和end()迭代器遍历列表 for (QList<int>::iterator it = list.begin(); it != list.end(); ++it) { std::cout << *it << " "; }
-
注意事项:
返回的迭代器是STL(标准模板库)风格的,这意味着它与C++ STL算法兼容,可以使用这些算法对
QList
进行操作。
QList::const_iterator QList::begin() const
-
函数说明:
这个重载的
begin
函数返回一个指向QList
容器中第一个元素的常量迭代器。与非const版本的begin
函数返回一个可修改的迭代器不同,这个版本的begin
函数返回的迭代器不允许修改元素的值。它只能用于读取元素。
QList::const_iterator QList::cbegin() const
-
函数说明:
cbegin
函数提供了对QList
容器开始位置的只读访问,返回的迭代器可以用于遍历列表中的元素,但不允许修改这些元素。返回的迭代器是STL风格的。
QList::reverse_iterator QList::rbegin()
-
函数说明:
rbegin
函数提供了对QList
容器进行逆序遍历的能力,返回的逆向迭代器指向按逆序排列的第一个元素,即最后一个元素 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; // 使用rbegin()和rend()迭代器逆序遍历列表 for (QList<int>::reverse_iterator it = list.rbegin(); it != list.rend(); ++it) { std::cout << *it << " "; }
-
注意事项:
返回的逆向迭代器遵循STL的迭代器规范,允许使用STL算法对容器进行逆序迭代。
QList::const_reverse_iterator QList::rbegin() const
-
函数说明:
这个重载的
rbegin
函数提供了对QList
容器进行只读逆序遍历的能力,返回的逆向迭代器可以用于逆序读取列表中的元素。
QList::const_reverse_iterator QList::crbegin() const
-
函数说明:
crbegin
函数提供了对QList
容器进行只读逆序遍历的能力。返回的逆向迭代器指向按逆序排列的第一个元素,即原本的最后一个元素。返回的逆向迭代器遵循STL的迭代器规范,允许使用STL算法对容器进行只读的逆序迭代。 -
示例:
const QList<int> list = {1, 2, 3, 4, 5}; // 使用crbegin()和crend()迭代器进行只读逆序遍历 for (QList<int>::const_reverse_iterator it = list.crbegin(); it != list.crend(); ++it) { std::cout << *it << " "; } std::cout << std::endl;
QList::const_iterator QList::constBegin() const
-
函数说明:
constBegin
函数提供了对QList
容器第一个元素的只读访问。返回的迭代器可以用于遍历列表中的元素,但不能修改元素的值。返回的迭代器是STL风格的,可以与C++ STL算法一起使用,进行只读迭代。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; // 使用constBegin()和constEnd()进行只读遍历 for (QList<int>::const_iterator it = list.constBegin(); it != list.constEnd(); ++it) { std::cout << *it << " "; }
9.2 end、cend、rend、crend、constEnd函数
QList::iterator QList::end()
-
函数说明:
end
函数返回一个迭代器,它指向QList
容器末尾的虚构位置(指向末尾之后的迭代器),即最后一个元素之后的位置。这个迭代器并不代表一个实际的元素,而是作为遍历容器的结束条件。 -
使用场景:
此函数通常与
begin
函数配合使用,用于在循环中遍历容器的所有元素。end
提供的迭代器用作循环的退出条件,确保不会访问到容器之外的内存。 -
示例:
QList<int> list = {1, 2, 3, 4, 5}; // 使用begin()和end()迭代器遍历列表 QList<int>::iterator it; for (it = list.begin(); it != list.end(); ++it) { std::cout << *it << " "; }
-
注意事项:
由于
end
返回的是指向末尾之后的迭代器,解引用这个迭代器是未定义行为。因此,它应当只用于比较操作,判断迭代器是否已经遍历完容器的所有元素。
QList::const_iterator QList::end() const
-
函数说明:
与非const版本的
end
函数不同,返回的迭代器不允许修改容器中的元素。
QList::const_iterator QList::cend() const
-
函数说明:
cend
函数提供了对QList
容器末尾之后虚构位置的只读访问。返回的只读迭代器可以用于逆序遍历或作为遍历结束的条件。
QList::reverse_iterator QList::rend()
-
函数说明:
rend
函数返回一个逆向迭代器,它指向QList
容器在逆序遍历时的结束位置之后。此函数通常与rbegin
函数配合使用,用于在循环中逆序遍历容器的所有元素。rend
提供的迭代器用作逆序循环的退出条件。 -
注意事项:
rend
返回的迭代器指向结束位置之后,因此不能解引用。它仅用于比较操作,以判断迭代器是否已经逆序遍历完容器的所有元素。
QList::const_reverse_iterator QList::rend() const
-
函数说明:
返回的迭代器是常量迭代器,因此只能用来读取元素,不能用来修改元素。这在需要避免修改容器内容的只读逆序遍历中非常有用。
QList::const_reverse_iterator QList::crend() const
-
函数说明:
与
rend
函数返回的可修改迭代器不同,crend
返回的迭代器是常量的,意味着它不能用于修改容器中的元素,只能用于读取。此函数通常与crbegin
函数配合使用,用于在循环中以只读方式逆序遍历容器的所有元素。crend
提供的迭代器用作逆序循环的退出条件。
QList::const_iterator QList::constEnd() const
-
函数说明:
constEnd
函数提供了对QList
容器末尾之后虚构位置的只读访问。返回的迭代器是常量的,意味着它不能用于修改容器中的元素,只能用于遍历到容器的结束。
9.3 erase函数–移除与迭代器向关联的项
QList::iterator QList::erase(QList::iterator pos)
-
函数说明:
从列表中移除与迭代器
pos
关联的项,并返回返回一个迭代器,指向移除元素之后(可能是end()
)。 -
示例:
QList<int> list = {1, 2, 3, 4, 5, 6}; // 移除索引为2的元素(即值为3的元素) QList<int>::iterator it = list.begin() + 2; it = list.erase(it); //1 2 4 5 6
-
注意事项:
使用
erase
函数后,原先迭代器pos
所指向的元素将不再存在,迭代器也会失效。返回的迭代器可用于继续遍历或删除操作。
QList::iterator QList::erase(QList::iterator begin, QList::iterator end)
-
函数说明:
这个重载的
erase
函数用于移除QList
中指定迭代器范围内的所有元素。返回一个迭代器,指向end
在调用之前所引用的那个元素。 -
示例:
QList<int> list = {1, 2, 3, 4, 5, 6, 7, 8, 9}; // 移除从索引1开始到索引4结束的元素(不包括索引4) QList<int>::iterator newEnd = list.erase(list.begin() + 1, list.begin() + 4);
-
注意事项:
使用
erase
函数后,从begin
到end
(不包括end
)的所有迭代器都会失效,因为它们所指向的元素已经被删除。返回的迭代器可用于继续遍历或删除操作。
10.QList支持的操作符函数
-
operator=
QList<T> &QList::operator=(QList<T> &&other) QList<T> &QList::operator=(const QList<T> &other)
-
operator!=
bool QList::operator!=(const QList<T> &other) const
-
operator+
QList<T> QList::operator+(const QList<T> &other) const
-
operator+=
QList<T> &QList::operator+=(const QList<T> &other)
-
operator<<
QList<T> &QList::operator<<(const QList<T> &other) QList<T> &QList::operator<<(const T &value) //Writes the list list to stream out template <typename T> QDataStream &operator<<(QDataStream &out, const QList<T> &list)
-
operator==
bool QList::operator==(const QList<T> &other) const
-
operator[]
T &QList::operator[](int i) const T &QList::operator[](int i) const
-
operator<
template <typename T> bool operator<(const QList<T> &lhs, const QList<T> &rhs)
-
operator<=
template <typename T> bool operator<=(const QList<T> &lhs, const QList<T> &rhs)
-
operator>
template <typename T> bool operator>(const QList<T> &lhs, const QList<T> &rhs)
-
operator>=
template <typename T> bool operator>=(const QList<T> &lhs, const QList<T> &rhs)
-
operator>>
//Reads a list from stream in into list. template <typename T> QDataStream &operator>>(QDataStream &in, QList<T> &list)