Qt - kontener typu QVector

Stronę tą wyświetlono już: 30 razy

Klasa QVector jest kolejnym typem kontenera wchodzącego w skład biblioteki Qt. Dysponuje on praktycznie tymi samymi metodami co omawiana klasa QList, jest jednak pewna zasadnicza różnica w tym, jak realizowane jest przechowywanie danych w pamięci. Okazuje się bowiem, że QVector zawsze przechowuje w pamięci elementy tak, że te zajmują kolejne miejsca w pamięci komputera podczas gdy QList przechowuje swoje elementy na stercie, chyba że rozmiar przechowywanych danych jest mniejszy lub równy rozmiarowi typu void*.

Klasa QVector umożliwia szybkie iterowanie po dużej liczbie elementów, ale dodawanie i usuwanie elementów z wnętrza nie jest tak szybkie jak w przypadku klasy QList co ma znaczenie zwłaszcza przy dużej liczbie danych i dużej ilości takich operacji.

Dodawanie elementów do obiektu klasy QVector

Dodanie kolejnych elementów można przeprowadzić na kilka różnych sposobów, jednym z nich jest przypisanie w stylu C++ 11:

Listing 1
  1. QVector<int> vector = {10, 20};
  2. qDebug() << vector;

Można również dodawać na różne sposoby kolejne elementy:

Listing 2
  1. QVector<int> vector = {10, 20};
  2. qDebug() << vector;
  3. vector.append(30);
  4. vector.append({40, 50});
  5. qDebug() << vector;
  6. vector.prepend(60);
  7. qDebug() << vector;
  8. vector << 70 << 80;
  9. qDebug() << vector;
  10. vector += 90;
  11. vector += {100, 110};
  12. qDebug() << vector;
  13. vector.push_back(120);
  14. vector.push_front(130);
  15. qDebug() << vector;
  16. vector.insert(vector.begin() + 2, 130);
  17. qDebug() << vector;

Wynik działania powyższego kodu:

QVector(10, 20)
QVector(10, 20, 30, 40, 50)
QVector(60, 10, 20, 30, 40, 50)
QVector(60, 10, 20, 30, 40, 50, 70, 80)
QVector(60, 10, 20, 30, 40, 50, 70, 80, 90, 100, 110)
QVector(130, 60, 10, 20, 30, 40, 50, 70, 80, 90, 100, 110, 120)
QVector(130, 60, 130, 10, 20, 30, 40, 50, 70, 80, 90, 100, 110, 120)

Pozyskiwanie informacji o liczbie elementów zawartych

Istnieją dwie metody length i size, które zwracają liczbę elementów zawartych w obiekcie klasy QVector.

Iterowanie po elementach wektora

Iterowanie można wykonać na kilka sposobów. Pierwszy z nich wykorzystuje indeksowanie:

Listing 3
  1. QVector<int> vector = {10, 20, 30};
  2. for(int i = 0; i < vector.length(); i++){
  3. qDebug() << vector[i]; // opcjonalnie vector.at(i)
  4. }

Można też iterować wykorzystując wskaźniki:

Listing 4
  1. QVector<int> vector = {10, 20, 30};
  2. for(QVector<int>::iterator i = vector.begin(); i < vector.end(); i++){
  3. qDebug() << *i;
  4. }

Jeżeli dodana została obsługa standardu C++ 11 można sobie ułatwić życie iterując w następujący sposób:

Listing 5
  1. QVector<int> vector = {10, 20, 30};
  2. for(auto element: vector){
  3. qDebug() << element;
  4. }

I w końcu można iterować po elementach listy w stylu Javy:

Listing 6
  1. QVector<int> vector = {10, 20, 30};
  2. QVectorIterator<int> javaStyleIterator(vector);
  3. while (javaStyleIterator.hasNext())
  4. qDebug() << javaStyleIterator.next();

Znalezienie indeksu pierwszego lub ostatniego wystąpienia danej wartości w wektorze

By znaleźć ostatni lub pierwszy indeks, pod którym znajduje się szukana wartość należy skorzystać z metody indexOf lub lastIndexOf w następujący sposób:

Listing 7
  1. QVector<int> vector = {10, 20, 30};
  2. int index = vector.indexOf(20);
  3. if(index != -1){
  4. qDebug() << index;
  5. }

Usuwanie elementów z wektora

Istnieje szereg metod, które umożliwiają usuwanie elementów z wektora QVector. Oto przykład ich użycia:

Listing 8
  1. QVector<int> data = {100, 200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800};
  2. qDebug() << data;
  3. data.removeAll(600); // usuwam wszystkie wartości równe 600
  4. qDebug() << data;
  5. data.removeFirst(); // usuwam pierwszy element
  6. qDebug() << data;
  7. data.removeLast(); // usuwam ostatni element
  8. qDebug() << data;
  9. data.removeAt(2); // usuwam 3 element (indeksowanie od 0)
  10. qDebug() << data;
  11. data.remove(4); // usuwa 5-ty element
  12. qDebug() << data;
  13. data.remove(1, 3); // usuwa trzy elementy zaczynając od drugiego
  14. qDebug() << data;
  15. data.erase(data.begin() + 1); // usuwanie drugiego elementu
  16. qDebug() << data;

Wynik działania powyższego kodu:

QVector(100, 200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800)
QVector(100, 200, 300, 400, 500, 700, 100, 300, 400, 500, 700, 800)
QVector(200, 300, 400, 500, 700, 100, 300, 400, 500, 700, 800)
QVector(200, 300, 400, 500, 700, 100, 300, 400, 500, 700)
QVector(200, 300, 500, 700, 100, 300, 400, 500, 700)
QVector(200, 300, 500, 700, 300, 400, 500, 700)
QVector(200, 300, 400, 500, 700)
QVector(200, 400, 500, 700)

Zdejmowanie pierwszego, ostatniego lub i-tego elementu wektora

Metody takeFirst. takeLast i takeAt umożliwiają zdjęcie pierwszego, ostatniego i i-tego elementu wektora z jednoczesnym jego zwróceniem.

Listing 9
  1. QVector<int> data = {100, 200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800};
  2. qDebug() << data;
  3. qDebug() << "Get first one: " << data.takeFirst();
  4. qDebug() << "After remove first one: " << data;
  5. qDebug() << "Get last one: " << data.takeLast();
  6. qDebug() << "After remove last one: " << data;
  7. qDebug() << "Get 3rd one: " << data.takeAt(2);
  8. qDebug() << "After remove 3rd one: " << data;

Wynik działania powyższego kodu:

QVector(100, 200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800)
Get first one:  100
After remove first one:  QVector(200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800)
Get last one:  800
After remove last one:  QVector(200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700)
Get 3rd one:  400
After remove 3rd one:  QVector(200, 300, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700)

Wyciąganie części elementów z wnętrza wektora

Metoda mid umożliwia wyciągnięcie dowolnej liczby elementów z wnętrza wektora. Oto przykład:

Listing 10
  1. QVector<int> data = {100, 200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800};
  2. QVector<int> subData = data.mid(3, 5);
  3. qDebug() << data;
  4. qDebug() << subData;

Wynik działania powyższego kodu:

QVector(100, 200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800)
QVector(400, 500, 600, 600, 700)

Przenoszenie elementu wektora

Metoda move umożliwia przeniesienie elementu o podanym indeksie na inną pozycję:

Listing 11
  1. QVector<int> data = { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0};
  2. qDebug() << data;
  3. data.move(5, 10);
  4. qDebug() << data;

Wynik działania powyższego kodu:

QVector(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0)
QVector(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)

Łączenie dwóch wektorów

Łączenie dwóch wektorów umożliwia operator dodawania z podstawianiem += oraz dodawania +. Oto przykład:

Listing 12
  1. QVector<int> data = {0, 1, 2};
  2. QVector<int> data2 = {3, 4, 5, 6};
  3. qDebug() << data + data2;
  4. data2 += data;
  5. qDebug() << data2;

Wynik działania powyższego kodu:

QVector(0, 1, 2, 3, 4, 5, 6)
QVector(3, 4, 5, 6, 0, 1, 2)

Zamiana elementów wektorów miejscami

Jeżeli zachodzi konieczność zamiany miejscami elementów dwóch wektorów, to najszybszą metodą wykonania tego zadania jest użycie metody swap w następujący sposób:

Listing 13
  1. QVector<int> data = {0, 1, 2};
  2. QVector<int> data2 = {3, 4, 5, 6};
  3. qDebug() << "Before swap: data =" << data << "data2 =" << data2;
  4. data.swap(data2);
  5. qDebug() << "After swap: data =" << data << "data2 =" << data2;

Wynik działania powyższego kodu:

Before swap: data = QVector(0, 1, 2) data2 = QVector(3, 4, 5, 6)
After swap: data = QVector(3, 4, 5, 6) data2 = QVector(0, 1, 2)
Strony powiązane
strony powiązane
  1. doc.qt.io/qt-5/qvector.html - strona dokumentacji Qt z opisem klasy QVector

Komentarze