Apakah ada cara di Jawa untuk setiap loop
for(String s : stringArray) {
doSomethingWith(s);
}
untuk mengetahui seberapa sering loop telah diproses?
Selain menggunakan for(int i=0; i < boundary; i++)
loop lama dan terkenal , adalah konstruknya
int i = 0;
for(String s : stringArray) {
doSomethingWith(s);
i++;
}
satu-satunya cara untuk memiliki penghitung seperti itu tersedia di setiap loop?
Type var = null; for (var : set) dosomething; if (var != null) then ...
Jawaban:
Tidak, tetapi Anda bisa menyediakan loket sendiri.
Alasan untuk ini adalah bahwa untuk-setiap loop secara internal tidak memiliki penghitung; itu didasarkan pada antarmuka Iterable , yaitu menggunakan
Iterator
untuk loop melalui "koleksi" - yang mungkin bukan koleksi sama sekali, dan mungkin sebenarnya sesuatu yang sama sekali tidak didasarkan pada indeks (seperti daftar tertaut).sumber
for(int idx=0, String s; s : stringArray; ++idx) doSomethingWith(s, idx);
each_with_index
metode loopEnumerable
di Ruby. Lihat apidock.com/ruby/Enumerable/each_with_indexfor
loop", sesuatu sepertifor (int i = 0; String s: stringArray; ++i)
Ada cara lain.
Mengingat bahwa Anda menulis
Index
kelas Anda sendiri dan metode statis yang mengembalikanIterable
contoh lebih dari kelas ini Anda bisaDi mana implementasi
With.index
adalah sesuatu sepertisumber
Solusi termudah adalah dengan menjalankan counter Anda sendiri dengan demikian:
Alasan untuk ini adalah karena tidak ada jaminan aktual bahwa item dalam koleksi (yang varian itu
for
berulang) bahkan memiliki indeks, atau bahkan memiliki urutan yang ditentukan (beberapa koleksi dapat mengubah urutan ketika Anda menambah atau menghapus elemen).Lihat misalnya, kode berikut:
Ketika Anda menjalankannya, Anda dapat melihat sesuatu seperti:
menunjukkan bahwa, memang demikian, urutan tidak dianggap sebagai fitur yang menonjol dari suatu set.
Ada beberapa cara lain untuk melakukannya tanpa penghitung manual, tetapi ini adalah pekerjaan yang adil untuk keuntungan yang meragukan.
sumber
Menggunakan lambdas dan antarmuka fungsional di Java 8 memungkinkan pembuatan abstraksi loop baru. Saya dapat mengulang koleksi dengan indeks dan ukuran koleksi:
Output yang mana:
Yang saya terapkan sebagai:
Kemungkinannya tidak terbatas. Misalnya, saya membuat abstraksi yang menggunakan fungsi khusus hanya untuk elemen pertama:
Yang mencetak daftar yang dipisahkan koma dengan benar:
Yang saya terapkan sebagai:
Perpustakaan akan mulai muncul untuk melakukan hal-hal semacam ini, atau Anda dapat menjalankannya sendiri.
sumber
Java 8 memperkenalkan metode
Iterable#forEach()
/Map#forEach()
, yang lebih efisien untuk banyakCollection
/Map
implementasi dibandingkan dengan "klasik" untuk-setiap loop. Namun, juga dalam hal ini indeks tidak disediakan. Kuncinya di sini adalah dengan menggunakan diAtomicInteger
luar ekspresi lambda. Catatan: variabel yang digunakan dalam ekspresi lambda harus final secara efektif, itu sebabnya kami tidak bisa menggunakan yang biasaint
.sumber
Saya khawatir ini tidak mungkin dengan
foreach
. Tetapi saya dapat menyarankan Anda untuk simpangan gaya lama yang simpel :Perhatikan bahwa, antarmuka Daftar memberi Anda akses ke
it.nextIndex()
.(edit)
Untuk contoh Anda yang diubah:
sumber
Salah satu perubahan
Sun
yang dipertimbangkanJava7
adalah untuk menyediakan akses keIterator
loop internal foreach. sintaksnya akan seperti ini (jika ini diterima):Ini adalah gula sintaksis, tetapi tampaknya banyak permintaan dibuat untuk fitur ini. Tetapi sampai disetujui, Anda harus menghitung iterasi sendiri, atau menggunakan regular untuk loop dengan
Iterator
.sumber
Solusi Idiomatik:
sumber
Meskipun ada begitu banyak cara lain yang disebutkan untuk mencapai hal yang sama, saya akan membagikan cara saya untuk beberapa pengguna yang tidak puas. Saya menggunakan fitur Java 8 IntStream.
1. Array
2. Daftar
sumber
Jika Anda membutuhkan penghitung di setiap loop, Anda harus menghitung sendiri. Tidak ada built in counter sejauh yang saya tahu.
sumber
Ada "varian" untuk menjawab pertanyaan ... ;-)
sumber
i=0; i++;
pendekatan yang tampaknya lebih jelas ?Untuk situasi di mana saya hanya perlu indeks sesekali, seperti dalam klausa menangkap, saya kadang-kadang akan menggunakan indexOf.
sumber
Solusi terbaik dan dioptimalkan adalah melakukan hal berikut:
Di mana Tipe dapat berupa tipe data apa pun dan tipe adalah variabel tempat Anda melamar.
sumber
Saya sedikit terkejut tidak ada yang menyarankan yang berikut (saya akui itu pendekatan malas ...); Jika stringArray adalah Daftar sejenis, Anda bisa menggunakan sesuatu seperti stringArray.indexOf (S) untuk mengembalikan nilai untuk hitungan saat ini.
Catatan: ini mengasumsikan bahwa elemen-elemen Daftar adalah unik, atau bahwa itu tidak masalah jika mereka tidak unik (karena dalam kasus itu akan mengembalikan indeks dari salinan pertama yang ditemukan).
Ada situasi di mana itu sudah cukup ...
sumber
Ini adalah contoh bagaimana saya melakukan ini. Ini mendapatkan indeks pada untuk setiap loop. Semoga ini membantu.
sumber