兩種QMultiMap的遍歷方法(最好使用只讀遍歷器)


留個爪,備查
    QMultiMap<QString, QString>& remote_map = my_obj->m_MapVersion; // ccc 這里體現了引用的好處,不必整個復制了
    qDebug() << "remote_map: " << remote_map.count();
    QMultiMap<QString, QString>& remote_fullmap = my_obj->m_MapFullVersion;
    qDebug() << "m_MapFullVersion: " << remote_fullmap.count();// 遍歷方法一
    QMutableMapIterator<QString, QString> i(remote_fullmap);
     while (i.hasNext()) {
        if (i.next().key().endsWith("__fixme__")) i.remove(); // fixme
        qDebug() << "remote1: " << i.key() << ",   " << i.value();
     }
     // 遍歷方法二
     foreach (const QString &strKey, remote_map.keys()) // values
      qDebug()  << "remote2: " << strKey << ":" << remote_map.value(strKey);

其中foreach是宏替換產生的語法

參考:
http://www.verydemo.com/cj.jsp?c=40&u=qt-rong-qi-lei-jie-shao-he-shi-yong
http://www.devbean.net/2013/01/qt-study-road-2-iterator/

 

  •  Qt 的容器類提供了兩種風格的遍歷器:Java 風格和 STL 風格。這兩種風格的遍歷器在通過非 const 函數對集合進行修改時都是不可用的。
      Java 風格的遍歷器
      Java 風格的遍歷器是在 Qt4 首先引入的,是 Qt 應用程序首先推薦使用的形式。這種風格比起 STL 風格的遍歷器更方便。方便的代價就是不如后者高效。它們的 API 非常類似於 Java 的遍歷器類,故名。
      每一種容器都有兩種 Java 風格的遍歷器:一種提供只讀訪問,一種提供讀寫訪問:

容器 只讀遍歷器 讀寫遍歷器
QList,QQueue QListIterator QMutableListIterator
QLinkedList QLinkedListIterator QMutableLinkedListIterator
QVector,QStack QVectorIterator QMutableVectorIterator
QSet QSetIterator QMutableSetIterator
QMap<key, t="">,QMultiMap<key, t=""> QMapIterator QMutableMapIterator
QHash<key, t="">,QMultiHash<key, t=""> QHashIterator QMutableHashIterator

  不同於下面我們將要介紹的 STL 風格的遍歷器,Java 風格的遍歷器指向的是兩個元素之間的位置,而不是指向元素本身。因此,它們可能會指向集合第一個元素之前的位置,也可能指向集合的最后一個元素之后的位置。
  我們通過調用hasNext()函數判斷遍歷器之后的位置上有無元素。如果有,調用next()函數將遍歷器跳過其后的元素。next()函數返回剛剛跳過的元素。當然,我們也可以使用hasPrevious()和previous()函數來從尾部開始遍歷,詳細內容可以參考 API 文檔。
  QListIterator是只讀遍歷器,不能插入或者刪除數據。如果需要這些操作,我們可以使用QMutableListIterator。
  STL 風格的遍歷器
  STL 風格的遍歷器從 Qt 2.0 就開始提供。這種遍歷器能夠兼容 Qt 和 STL 的通用算法,並且為速度進行了優化。同 Java 風格遍歷器類似,Qt 也提供了兩種 STL 風格的遍歷器:一種是只讀訪問,一種是讀寫訪問。我們推薦盡可能使用只讀訪問,因為它們要比讀寫訪問的遍歷器快一些。

容器 只讀遍歷器 讀寫遍歷器
QList,QQueue QList::const_iterator QList::iterator
QLinkedList QLinkedList::const_iterator QLinkedList::iterator
QVector,QStack QVector::const_iterator QVector::iterator
QSet QSet::const_iterator QSet::iterator
QMap<key, t="">,QMultiMap<key, t=""> QMap<key, t="">::const_iterator QMap<key, t="">::iterator
QHash<key, t="">,QMultiHash<key, t=""> QHash<key, t="">::const_iterator QHash<key, t="">::iterator

  STL 風格的遍歷器具有類似數組指針的行為。例如,我們可以使用 ++ 運算符讓遍歷器移動到下一個元素,使用 運算符獲取遍歷器所指的元素。對於QVector和QStack,雖然它們是在連續內存區存儲元素,遍歷器類型是`typedef T ,const_iterator類型則是typedef const T *`。
  不同於 Java 風格遍歷器,STL 風格遍歷器直接指向元素本身。容器的begin()函數返回指向該容器第一個元素的遍歷器;end()函數返回指向該容器最后一個元素之后的元素的遍歷器。end()實際是一個非法位置,永遠不可達。這是為跳出循環做的一個虛元素。如果集合是空的,begin()等於end(),我們就不能執行循環。
  由於有隱式數據共享(我們會在后面的章節介紹該部分內容),即使一個函數返回集合中元素的值也不會有很大的代價。Qt API 包含了很多以值的形式返回QList或QStringList的函數(例如QSplitter::sizes())。如果你希望使用 STL 風格的遍歷器遍歷這樣的元素,應該使用容器的拷貝,例如:

1
2
3
4
5
6
7
8
9
10
11
// 正確的方式
const QList<QString> sizes = splitter->sizes();
QList<QString>::const_iterator i;
for (i = sizes.begin(); i != sizes.end(); ++i)
...
 
// 錯誤的方式
QList<QString>::const_iterator i;
for (i = splitter->sizes().begin();
i != splitter->sizes().end(); ++i)
...

  這個問題不存在於那些返回集合的 const 或非 const 引用的函數。隱式數據共享對 STL 風格遍歷器造成的另外影響是,在容器上運行着非 const 遍歷器的時候,不能對容器進行拷貝。Java 風格的遍歷器沒有這個問題。
  foreach關鍵字
  如果類型名中帶有逗號,比如QPair<int, int="">,我們只能像上面一樣,先創建一個對象,然后使用foreach關鍵字。如果沒有逗號,則可以直接在foreach關鍵字中使用新的對象。
  Qt 會在foreach循環時自動拷貝容器。這意味着,如果在遍歷時修改集合,對於正在進行的遍歷是沒有影響的。即使不修改容器,拷貝也是會發生的。但是由於存在隱式數據共享,這種拷貝還是非常迅速的。
  因為foreach創建了集合的拷貝,使用集合的非 const 引用也不能實際修改原始集合,所修改的只是這個拷貝。

http://jukezhang.com/2014/11/23/learn-qt-eight/  《QT學習之路2》摘錄-6(容器)

http://www.devbean.net/2013/01/qt-study-road-2-iterator/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM