Qlist

QList是一種表示鏈表的模板類。
QList<T>是Qt的一種泛型容器類。它以鏈表方式存儲一組值,並能對這組數據進行快速索引,
還提供了快速插入和刪除等操作。
QList、QLinkedList和QVector提供的操作極其相似:
* 對大多數操作來說,我們用QList就可以了。其API是基於索引(index)的,因此用起來比QLinkedList更方便(QLinkedList的API是基於迭代器的)。QList比QVector更快,這是由它
們在內存中的存儲方式決定的。
* 需要使用QLinkedList的地方:
* 需要使用QVector的地方:元素的儲存位置彼此相鄰。

QList<T>表示爲一組指向被存儲元素的數組。(例外,如果T本身就是指針類型,或者是size不
大於指針類型的基本類型,或者是Qt的共享類,那麼QList<T>會直接在指針數組中存儲這些元素
。)元素個數小於1000的QList能夠很快地實現在鏈表中間插入操作,以及快速的查找操作。此
外,由於QList在鏈表兩端都預先分配了內存,因此實現prepend()和append()操作都很快。
注意:對於size比指針大的共享類,使用QVector會更好。

以下是兩個分別存儲int型數據和QDate類型數據的鏈表:
QList<int> intList;
QList<QDate> dateList;
對於字符串鏈表,Qt提供了QStringList類。它繼承自QList,但還提供了一些其他便於使用字符
串的函數:QStringList::join()、QStringList::find()、QStringList::split()。

QList以鏈表形式存儲一組元素。默認爲空鏈表,我們可以使用<<操作符添加元素:
QList<QString> list;
list << "one" << "two" << "three"; // list: ["one", "two", "three"]
QList提供了一系列添加、移動、刪除元素的操作:insert(), replace(), removeAt(), swap()
。此外,它還提供了便於操作的函數:append(), prepend(), removeFirst(), removeLast()。
QList與C++中數組的索引方式一樣,都是從0開始的。我們可以使用[]操作符來訪問位於索引值
處的元素。對於非const鏈表,操作符[]返回的是該元素的引用,並且返回值可以用途左操作數。
if ( list[0] == "Bob" )
   list[0] = "Robert";
由於QList是以指針數組的形式實現的,該操作能夠很快地實現(時間複雜度爲常數)。對於只讀
訪問,我們可以用at()函數實現訪問:
for ( int i=0; i!=list.size(); ++i )
{
   if ( list.at(i) == "Jane" )
   { cout << "Found Jane at position:" << i<< endl;}
}
at()操作比操作符[]更快,因爲它不需要深度複製(deep copy)。
QList的一個常用操作是,從鏈表中取出一個元素(元素不再在鏈表之中),並對該元素進行操作。
QList提供了以下操作來實現此功能:takeAt()、takeFirst()、takeLast()。以下是一個示例:
QList<QWidget *> list;
...
while ( !list.isEmpty() )
   deleta list.takeFirst();
由於QList在鏈表兩端都預先分配了緩存以應對鏈表兩端的快速添加操作,這樣就使得在QList的
兩端插入或刪除元素變得非常地快。
如果需要找出某個值在鏈表中出現的位置,我們可以使用indexOf()、lastIndexOf()函數來實現。
前者進行前向查找,而後者則進行反向查找。兩者都會在找到匹配元素後返回該元素的索引值。若
沒有找到匹配元素,則返回-1。例如:
int i = indexOf("Jane");
if ( i!=-1 )
   cout << "First occurance of Jane is at position" << i << endl;

如果僅僅是想判斷鏈表中是否包含某一值,我們可以使用函數contains()。如果希望知道某一值在
鏈表中的出現次數,使用count()函數。如果要替換掉鏈表中所有值與某一值相同的元素,使用
replace()。

QList的值必須是可數的類型。這包含了我們常用的大多數類型。但是,如果我們存儲QWidget類型
的話,編譯器也不會通知我們出錯了。但是,我們應該使用QWidget *,而不是QWidget。此外,一
些函數還作出了其它限制,比如:indexOf()和lastIndexOf()操作要求值的類型能進行“==”操作。

與其他容器一樣,QList也提供了Java形式的迭代器(QListIterator和QMutableListIterator)。
以及STL形式的迭代器(QList::const_iterator和QList::iterator)。實際上,由於可通過索引值
來訪問元素,我們很少使用這些迭代器。使用索引值訪問元素的速度與迭代器相差無幾。

爲了提高效率,QList的成員函數在使用前並不會驗證其參數是否有效。除isEmpty()函數外,其它
成員函數都會假定該容器爲非空容器;使用索引值(index)進行操作的成員函數都會假定其索引值參
數是在有效範圍內的。這就意味着,QList在有些時候會出錯。如果在編譯時,我們定義了QT_NO_DEBUG
,編譯過程中就不會檢測這些錯誤。如果沒有定義QT_NO_DEBUG,我們可以利用Q_ASSERT()或者
Q_ASSERT_X()加上一些合理的信息來實現錯誤檢測。

我們可以在調用其他函數之前先調用isEmpty()函數判斷鏈表是否爲空,以避免對空鏈表進行錯
誤操作。而對於以索引值index爲參數的成員函數,我們還需要判斷該索引值是否位於有效範圍
內。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章