Bagaimana cara mendapatkan indeks loop saat menggunakan Iterator?

108

Saya menggunakan Iterator untuk mengulang melalui koleksi dan saya ingin mendapatkan indeks elemen saat ini.

Bagaimana saya bisa melakukan itu?

Mahmoud Saleh
sumber
1
@ Finnw Saya tidak berpikir bahwa mereka adalah duplikat. Pertanyaan ini diajukan menggunakan Iterator, yang lainnya menggunakan for-each loop. Kedua soal tersebut diselesaikan dengan pendekatan yang serupa, jadi jawabannya adalah duplikat bukan soal.
Robert

Jawaban:

92

Gunakan variabel Anda sendiri dan tingkatkan dalam loop.

Chris Diver
sumber
6
Tetapi juga lihat saran @ mateusz-dymczyk tentang it.nextIndex(). Berguna jika koleksi adalah List.
noamtm
113

Saya memiliki pertanyaan yang sama dan menemukan menggunakan ListIterator bekerja. Mirip dengan tes di atas:

List<String> list = Arrays.asList("zero", "one", "two");

ListIterator iter = list.listIterator();

while (iter.hasNext()) {
    System.out.println("index: " + iter.nextIndex() + " value: " + iter.next());
}

Pastikan Anda memanggil nextIndex SEBELUM Anda benar-benar mendapatkan next ().

Paul
sumber
5
Terima kasih telah menyebutkan 'Pastikan Anda menelepon Indeks berikutnya SEBELUM Anda benar-benar mendapatkan indeks berikutnya ()'
Gangadhar JANNU
Terima kasih, saya tidak tahu tentang ini sebelumnya. Perhatian yang akan saya buat adalah ListIterator dua arah sedangkan Iterator searah. Selama Anda menghindari bergerak maju mundur dengan kursor yang efektif, maka Anda harus aman.
pengguna2910265
28

Berikut cara untuk melakukannya menggunakan variabel Anda sendiri dan membuatnya tetap ringkas:

List<String> list = Arrays.asList("zero", "one", "two");

int i = 0;
for (Iterator<String> it = list.iterator(); it.hasNext(); i++) {
    String s = it.next();
    System.out.println(i + ": " + s);
}

Output (Anda dapat menebaknya):

0: zero
1: one
2: two

Keuntungannya adalah Anda tidak menaikkan indeks Anda di dalam loop (meskipun Anda harus berhati-hati untuk hanya memanggil Iterator # next sekali per loop - lakukan saja di atas).

Tom Clift
sumber
3
Jika Anda membuat iterator sendiri, Anda juga dapat menggunakan ListIterator dan tidak memerlukan variabel int terpisah.
Robert Klemme
1
Jika Anda menggunakan 'impor statis' untuk Arrays.asList maka Anda cukup menulisasList("zero", "one", "two")
karmakaze
Persis seperti itulah yang saya lakukan sebelum saya membaca jawaban dari Paulus. Saya akan sangat mengecilkan cara Anda, karena saya tidak melihat keuntungan apa pun darinya. Apakah menurut Anda ada keuntungan (kecuali yang disebutkan). Mengapa Anda tidak menggunakan for-each loop? Mendefinisikan Iterator secara eksplisit tidak diperlukan, jika Anda menggunakan variabel Anda sendiri.
Willi Mentzel
@progressive_overload hanya jika Anda memerlukan Iterator (sesuai pertanyaan, misalnya untuk meneruskan ke perpustakaan), yang tidak ditampilkan contoh. Dalam contoh ini, Anda memiliki variabel di luar loop dan harus berhati-hati untuk memanggil #next sekali. Dalam contoh Paul tidak ada variabel di luar loop, tetapi Anda harus berhati-hati untuk memanggil #next dan #nextIndex bersama-sama sekali (dan dalam praktiknya, jika digunakan lebih dari sekali, mereka akan ditarik ke variabel lokal, yang contoh itu tidak ' t menunjukkan).
Tom Clift
23

Anda dapat menggunakan ListIteratoruntuk melakukan penghitungan:

final List<String> list = Arrays.asList("zero", "one", "two", "three");

for (final ListIterator<String> it = list.listIterator(); it.hasNext();) {
    final String s = it.next();
    System.out.println(it.previousIndex() + ": " + s);
}
Robert Klemme
sumber
12

Koleksi seperti apa? Jika itu adalah implementasi dari antarmuka Daftar maka Anda bisa menggunakan it.nextIndex() - 1.

Mateusz Dymczyk
sumber
4

Gunakan ListIterator untuk mengulangi Koleksi. Jika Koleksi bukan Daftar untuk memulai, gunakan Arrays.asList(Collection.toArray())untuk mengubahnya menjadi Daftar terlebih dahulu.

Jatin
sumber
3

lakukan saja seperti ini:

        ListIterator<String> it = list1.listIterator();
        int index = -1;
        while (it.hasNext()) {
            index++;
            String value = it.next();
            //At this point the index can be checked for the current element.

        }
Cerah
sumber
4
Memanggil indexOf () akan membutuhkan pemindaian tambahan dari daftar perangkat. Akan lebih cepat jika hanya menaikkan penghitung lokal.
Greg Brown
1
sepakat. ini bukan solusi yang paling efisien.
Cerah
1
Sepertinya Anda memperbarui contoh agar lebih efisien.
Greg Brown
2

Gunakan int dan tingkatkan dalam loop Anda.

Florian Reischl
sumber
1

Lihat disini .

iterator.nextIndex()akan memberikan indeks elemen yang akan dikembalikan oleh panggilan berikutnya ke next().

riang
sumber
Antarmuka Iterator TIDAK memiliki metode nextIndex (). Anda perlu secara eksplisit menggunakan ListIterator untuk itu, tetapi OP mempertanyakan secara khusus tentang Iterator.
Fran Marzoa
0

Yang Anda butuhkan untuk menggunakannya adalah iterator.nextIndex () untuk mengembalikan indeks saat ini tempat iterator aktif. Ini bisa sedikit lebih mudah daripada menggunakan variabel penghitung Anda sendiri (yang masih berfungsi juga).

public static void main(String[] args) {    
    String[] str1 = {"list item 1", "list item 2", "list item 3", "list item 4"};
    List<String> list1 = new ArrayList<String>(Arrays.asList(str1));

    ListIterator<String> it = list1.listIterator();

    int x = 0;

    //The iterator.nextIndex() will return the index for you.
    while(it.hasNext()){
        int i = it.nextIndex();
        System.out.println(it.next() + " is at index" + i); 
    }
}

Kode ini akan melalui list1 daftar satu item pada satu waktu dan mencetak teks item, lalu "ada di indeks" kemudian akan mencetak indeks yang ditemukan oleh iterator. :)

Ryan
sumber
1
Sebenarnya, kode Anda dimatikan satu per satu karena mencoba menampilkan indeks SETELAH memanggilnya.next ().
Henrik Aasted Sørensen
0

Meskipun Anda sudah punya jawabannya, berpikir untuk menambahkan beberapa info.

Seperti yang Anda sebutkan Koleksi secara eksplisit, Anda tidak dapat menggunakan listIteratoruntuk mendapatkan indeks untuk semua jenis koleksi.

Antarmuka daftar - ArrayList, LinkedList, Vector dan Stack.

Memiliki keduanya iterator()danlistIterator()

Set antarmuka - HashSet, LinkedHashSet, TreeSet dan EnumSet.

Hanya memiliki iterator()

Antarmuka peta - HashMap, LinkedHashMap, TreeMap, dan IdentityHashMap

Tidak memiliki iterator, tetapi dapat diiterasi menggunakan keySet()/ values()atau entrySet()sebagai keySet()dan entrySet()kembali Setdan values()kembali Collection.

Jadi lebih baik digunakan iterators()dengan kenaikan nilai yang berkelanjutan untuk mendapatkan indeks saat ini untuk semua jenis koleksi.

Vignesh Raja
sumber
-1

Ini akan menjadi solusi paling sederhana!

std::vector<double> v (5);

for(auto itr = v.begin();itr != v.end();++itr){

 auto current_loop_index = itr - v.begin();

  std::cout << current_loop_index << std::endl;

}

Diuji pada gcc-9 dengan -std=c++11bendera

Keluaran:

0
1
2
3
4

Sahabat
sumber