容器是通用类,用于将给定类型的项存储在内存中。C++有标准模板库(STL)有自己的容器。在Qt中可以使用Qt容器或STL容器。
有两种容器:顺序和关联。顺序容器一个接一个地存储项目,而关联容器存储键值对。QList
, QVector
, QLinkedList
属于顺序容器;QMap
, QHash
属于关联容器。
QVector
是一个提供动态数组的模板类。它将其元素存储在相邻的内存位置,并提供快速的基于索引的访问。对于大型不连续的元素,插入操作较慢,建议使用QList
。
// myvector.cpp
#include
#include
int main(void) {
QTextStream out(stdout);
QVector<int> vals = {1, 2, 3, 4, 5}; // 创建一个整型的容器
// size()方法获取容器长度,即元素数量
out << "The size of the vector is: " << vals.size() << endl;
// first()返回容器的第一个元素,last()返回容器的最后一个元素
out << "The first item is: " << vals.first() << endl;
out << "The last item is: " << vals.last() << endl;
vals.append(6); // append()在容器最后一个元素之后添加
vals.prepend(0); // prepend()在容器的第一个元素之前添加元素
out << "Elements: ";
// 通过容器输出容器内容
for (int val : vals) {
out << val << " ";
}
out << endl;
return 0;
}
输出结果为:
$ ./myvector
The size of the vector is: 5
The first item is: 1
The last item is: 5
Elements: 0 1 2 3 4 5 6
QList
是创建元素列表的容器,它与QVector
类似,它存储值列表并提供快速的基于索引的访问以及快速插入和删除。它是Qt中最常用的容器之一。
// mylist.cpp
#include
#include
#include
int main(void) {
QTextStream out(stdout);
// 创建一个QList容器
QList authors = {"Balzac", "Tolstoy",
"Gulbranssen", "London"};
for (int i=0; i < authors.size(); ++i) {
out << authors.at(i) << endl;
}
// 通过<<操作符像容器中添加两个新的元素
authors << "Galsworthy" << "Sienkiewicz";
out << "***********************" << endl;
// std::sort()采用升序的方法对容器内容进行排序
std::sort(authors.begin(), authors.end());
out << "Sorted:" << endl;
for (QString author : authors) {
out << author << endl;
}
}
输出结果为:
$ ./mylist
Balzac
Tolstoy
Gulbranssen
London
***********************
Sorted:
Balzac
Galsworthy
Gulbranssen
London
Sienkiewicz
Tolstoy
QStringList
是一个便利的容器,用于提供字符串列表。它具有快速的基于索引的访问以及快速插入和删除。
// mystringlist.cpp
#include
#include
int main(void) {
QTextStream out(stdout);
QString string = "coin, book, cup, pencil, clock, bookmark";
QStringList items = string.split(",");
QStringListIterator it(items);
while (it.hasNext()) {
out << it.next().trimmed() << endl;
}
}
在这个例子中,我们从一个字符串中创建一个字符串列表并将这些元素打印到控制台中。
QString string = "coin, book, cup, pencil, clock, bookmark";
QStringList items = string.split(",");
QString
的split()
方法根据提供的分隔符将字符串切割成子字符串。子字符串返回列表中。
QStringListIterator it(items);
QStringListIterator
为QStringList
提供了一个java样式的const迭代器。
while (it.hasNext()) {
out << it.next().trimmed() << endl;
}
hasNext()
方法用于判断是否到达容器的最后一个元素,trimmed()
用于对字符串序列中元素的空格进行修剪(大概就是在不应该出现的地方删除空格,例如每个单词最前面和最后面的)。
输出结果为:
$ ./mystringlist
coin
book
cup
pencil
clock
bookmark
qset提供了一个快速查找的单值数学集。这些值以未指定的顺序存储。
// myset.cpp
#include
#include
#include
#include
int main(void) {
QTextStream out(stdout);
// 创建了两个颜色集合,并且blue在两个集合中都存在
QSet cols1 = {"yellow", "red", "blue"};
QSet cols2 = {"blue", "pink", "orange"};
// size()方法返回集合的大小
out << "There are " << cols1.size() << " values in the set" << endl;
// insert()方法用于向集合中添加元素
cols1.insert("brown");
out << "There are " << cols1.size() << " values in the set" << endl;
cols1.unite(cols2);
out << "There are " << cols1.size() << " values in the set" << endl;
for (QString val : cols1) {
out << val << endl;
}
QList lcols = cols1.values();
std::sort(lcols.begin(), lcols.end());
out << "*********************" << endl;
out << "Sorted:" << endl;
for (QString val : lcols) {
out << val << endl;
}
return 0;
}
在这个例子中,QSet
用于存储颜色。
cols1.unite(cols2);
unite()
方法将两个集合合并。cols1
集合将从cols2
集合中插入所有cols1
中不存在的元素。
QList lcols = cols1.values();
std::sort(lcols.begin(), lcols.end());
不支持对一个集合进行排序。但是可以从一个集合中创建一个列表并对其进行排序。values()
方法返回一个包含集合中元素的新QList
。QList
中元素的顺序是未定义的。
输出结果为:
$ ./myset
There are 3 values in the set
There are 4 values in the set
There are 6 values in the set
blue
orange
red
brown
pink
yellow
*********************
Sorted:
blue
brown
orange
pink
red
yellow
QMap
是一个存储键值对的关联型数组(字典)。提供了与键关联的值的快速查找。
// myqmap.cpp
#include
#include
int main(void) {
QTextStream out(stdout);
// 创建一个QMap
QMapint> items = { {"coins", 5}, {"books", 3} };
// 通过insert()方法添加元素
items.insert("bottles", 7);
QList<int> values = items.values();
out << "Values:" << endl;
for (int val : values) {
out << val << endl;
}
QList keys = items.keys();
out << "Keys:" << endl;
for (QString key : keys) {
out << key << endl;
}
// QMapIterator是QMap的java样式迭代器,用来迭代map的元素。
QMapIteratorint> it(items);
out << "Pairs:" << endl;
while (it.hasNext()) {
it.next();
out << it.key() << ": " << it.value() << endl;
}
}
在这个例子中,我们有一个字典,我们将字符串键映射到整数值。
QList<int> values = items.values();
out << "Values:" << endl;
for (int val : values) {
out << val << endl;
}
获取字典的所有值并将它们打印到控制台。values()
方法返回一个映射值列表。
QList keys = items.keys();
out << "Keys:" << endl;
for (QString key : keys) {
out << key << endl;
}
同样,我们打印字典的所有键。keys()
方法返回一个包含字典中所有键的列表。
while (it.hasNext()) {
it.next();
out << it.key() << ": " << it.value() << endl;
}
在迭代器的帮助下,我们遍历map的所有元素。key()
方法返回当前键,value()
方法返回当前值。
输出结果为:
$ ./mymap
Values:
3
7
5
Keys:
books
bottles
coins
Pairs:
books: 3
bottles: 7
coins: 5
在下面的例子中,我们将在QList
中对自定义类的对象进行排序。
// book.h
class Book {
public:
Book(QString, QString);
QString getAuthor() const;
QString getTitle() const;
private:
QString author;
QString title;
};
这是我们自定义Book
类的头文件。
// book.cpp
#include
#include "book.h"
Book::Book(QString auth, QString tit) {
author = auth;
title = tit;
}
QString Book::getAuthor() const {
return author;
}
QString Book::getTitle() const {
return title;
}
这是Book
类的实现,有两个访问器方法。
// sortcustomclass.cpp
#include
#include
#include
#include "book.h"
// compareByTitle()是排序算法使用的比较函数。
bool compareByTitle(const Book &b1, const Book &b2) {
return b1.getTitle() < b2.getTitle();
}
int main(void) {
QTextStream out(stdout);
QList books = {
Book("Jack London", "The Call of the Wild"),
Book("Honoré de Balzac", "Father Goriot"),
Book("Leo Tolstoy", "War and Peace"),
Book("Gustave Flaubert", "Sentimental education"),
Book("Guy de Maupassant", "Une vie"),
Book("William Shakespeare", "Hamlet")
};
// std::sort算法按书的标题对列表中的书籍进行排序。
std::sort(books.begin(), books.end(), compareByTitle);
for (Book book : books) {
out << book.getAuthor() << ": " << book.getTitle() << endl;
}
}
在这个例子中,我们创建了一些Book
对象,并用std::sort
算法对它们进行排序。
输出结果为:
$ ./sortcustomclass
Honoré de Balzac: Father Goriot
William Shakespeare: Hamlet
Gustave Flaubert: Sentimental education
Jack London: The Call of the Wild
Guy de Maupassant: Une vie
Leo Tolstoy: War and Peace