Mempertimbangkan:
List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
System.out.println(item);
}
Seperti apa for
loop ekivalen itu tanpa menggunakan sintaks untuk masing-masing ?
java
foreach
syntactic-sugar
Jay R.
sumber
sumber
Jawaban:
Perhatikan bahwa jika Anda perlu menggunakan
i.remove();
dalam loop Anda, atau mengakses iterator yang sebenarnya dalam beberapa cara, Anda tidak dapat menggunakanfor ( : )
idiom, karena iterator yang sebenarnya hanya disimpulkan.Seperti yang dicatat oleh Denis Bueno, kode ini berfungsi untuk objek apa pun yang mengimplementasikan
Iterable
antarmuka .Juga, jika sisi kanan
for (:)
idiom adalaharray
bukanIterable
objek, kode internal menggunakan penghitung indeks int dan memeriksaarray.length
sebaliknya. Lihat Spesifikasi Bahasa Jawa .sumber
import java.util.Iterator;
danimport java.lang.Iterable;
java.util.Iterator
tidak diterapkanIterable
sehingga Anda tidak bisafor(String s : (Iterator<String>)foo)
. Saya mengerti mengapa hal ini, tetapi yang menjengkelkan.Konstruk untuk masing-masing juga berlaku untuk array. misalnya
yang pada dasarnya setara dengan
Jadi, ringkasan keseluruhan:
[nsayer] Berikut ini adalah bentuk yang lebih panjang dari apa yang terjadi:
[Denis Bueno]
sumber
The
foreach
Loop , ditambahkan dalam Java 5 (juga disebut "disempurnakan untuk loop"), setara dengan menggunakanjava.util.Iterator
sintaksis gula --Itu untuk hal yang sama. Karena itu, ketika membaca setiap elemen, satu per satu dan berurutan, aforeach
harus selalu dipilih daripada iterator, karena lebih nyaman dan ringkas.untuk setiap
Iterator
Ada situasi di mana Anda harus menggunakan secara
Iterator
langsung. Misalnya, mencoba menghapus elemen saat menggunakanforeach
kaleng (akan?) Menghasilkan aConcurrentModificationException
.foreach
vsfor
.: Perbedaan mendasarSatu-satunya perbedaan praktis antara
for
danforeach
adalah, dalam hal objek yang dapat diindeks, Anda tidak memiliki akses ke indeks. Contoh ketikafor
loop dasar diperlukan:Meskipun Anda bisa secara manual membuat indeks terpisah dengan variabel
foreach
,itu tidak disarankan, karena variabel-lingkup tidak ideal, dan
for
loop dasar hanyalah format standar dan yang diharapkan untuk kasus penggunaan ini.foreach
vsfor
.: KinerjaSaat mengakses koleksi, a
foreach
secara signifikan lebih cepat darifor
akses larik loop dasar . Ketika mengakses array, namun - setidaknya dengan array primitif dan wrapper - akses melalui indeks secara dramatis lebih cepat.Mengatur waktu perbedaan antara akses iterator dan indeks untuk array int-primitif
Indeks adalah 23- 40 persen lebih cepat dari iterator ketika mengakses
int
atauInteger
array. Berikut ini adalah output dari kelas pengujian di bagian bawah posting ini, yang merangkum angka-angka dalam array elemen-primitif 100-elemen (A adalah iterator, B adalah indeks):Saya juga menjalankan ini untuk
Integer
array, dan indeks masih merupakan pemenang yang jelas, tetapi hanya antara 18 dan 25 persen lebih cepat.Untuk koleksi, iterator lebih cepat dari indeks
Untuk
List
ofIntegers
Namun, iterator adalah pemenang yang jelas. Cukup ubah int-array di kelas uji menjadi:Dan buat perubahan yang diperlukan pada fungsi uji (
int[]
keList<Integer>
,length
kesize()
, dll.):Dalam satu tes mereka hampir setara, tetapi dengan koleksi, iterator menang.
* Posting ini didasarkan pada dua jawaban yang saya tulis di Stack Overflow:
Penggunaan dan sintaks untuk setiap loop di Jawa
Haruskah saya menggunakan Iterator atau forloop untuk beralih?
Beberapa informasi lebih lanjut: Mana yang lebih efisien, untuk setiap loop, atau iterator?
Kelas pengujian lengkap
Saya membuat kelas perbandingan-waktu-dibutuhkan-untuk-melakukan-dua-hal ini setelah membaca pertanyaan ini di Stack Overflow:
sumber
for(int value : int_array) {/* loop content */}
paling lambat dalam tes Anda karena secara sintaksis setara denganfor(int i = 0; i < int_array.length; i++) {int value = int_array[i]; /* loop content */}
, yang tidak sebanding dengan tes Anda.int value = int_array[i];
pada awal untuk loop, maka mereka mungkin juga menggunakan foreach. Kecuali mereka membutuhkan akses ke indeks juga, untuk beberapa alasan. Singkatnya, itu semua tergantung pada konteks.)Berikut ini adalah jawaban yang tidak mengasumsikan pengetahuan tentang Java Iterators. Ini kurang tepat, tetapi berguna untuk pendidikan.
Saat pemrograman kita sering menulis kode yang terlihat seperti berikut:
Sintaks foreach memungkinkan pola umum ini ditulis dalam cara yang lebih alami dan kurang berisik secara sintaksis.
Selain itu sintaks ini berlaku untuk objek seperti Daftar atau Set yang tidak mendukung pengindeksan array, tetapi yang mengimplementasikan antarmuka Java Iterable.
sumber
Untuk-setiap loop di Jawa menggunakan mekanisme iterator yang mendasarinya. Jadi identik dengan yang berikut:
sumber
Dalam fitur Java 8 Anda dapat menggunakan ini:
Keluaran
sumber
Ini tersirat oleh jawaban nsayer, tetapi perlu dicatat bahwa sintaks OP untuk (..) akan bekerja ketika "someList" adalah apa pun yang mengimplementasikan java.lang. Dapat diubah - tidak harus berupa daftar, atau koleksi dari java.util. Bahkan tipe Anda sendiri, oleh karena itu, dapat digunakan dengan sintaks ini.
sumber
Sebagaimana didefinisikan dalam JLS untuk-setiap loop dapat memiliki dua bentuk:
Jika jenis Ekspresi adalah subtipe dari
Iterable
maka terjemahan adalah sebagai:Jika Ekspresi tentu memiliki tipe array
T[]
maka:Java 8 telah memperkenalkan stream yang berkinerja lebih baik secara umum. Kita dapat menggunakannya sebagai:
sumber
Sintaks loop foreach adalah:
Contoh:
Keluaran:
PERINGATAN: Anda dapat mengakses elemen array dengan loop foreach, tetapi Anda TIDAK dapat menginisialisasi mereka. Gunakan
for
loop asli untuk itu.PERINGATAN: Anda harus mencocokkan jenis array dengan objek lain.
Jika Anda ingin mengedit elemen, gunakan
for
loop asli seperti ini:Sekarang jika kita membuang s ke konsol, kita mendapatkan:
sumber
Konstruk loop Java "untuk-masing-masing" akan memungkinkan iterasi atas dua jenis objek:
T[]
(array jenis apa pun)java.lang.Iterable<T>
The
Iterable<T>
antarmuka hanya memiliki satu metode:Iterator<T> iterator()
. Ini berfungsi pada objek bertipeCollection<T>
karenaCollection<T>
antarmuka memanjangIterable<T>
.sumber
Konsep loop foreach seperti yang disebutkan dalam Wikipedia disorot di bawah ini:
Jadi konsep loop foreach menjelaskan bahwa loop tidak menggunakan penghitung eksplisit yang berarti bahwa tidak perlu menggunakan indeks untuk melintasi dalam daftar sehingga menghemat pengguna dari kesalahan satu per satu. Untuk menjelaskan konsep umum dari kesalahan satu-per-satu ini, mari kita ambil contoh loop untuk melintasi dalam daftar menggunakan indeks.
Tetapi anggaplah jika daftar dimulai dengan indeks 1 maka loop ini akan melempar pengecualian karena tidak akan menemukan elemen pada indeks 0 dan kesalahan ini disebut kesalahan satu-per-satu. Jadi untuk menghindari kesalahan off-by-one ini digunakan konsep foreach loop. Mungkin ada keuntungan lain juga, tapi ini yang saya pikir adalah konsep utama dan keuntungan menggunakan foreach loop.
sumber
Di Java 8, mereka memperkenalkan forach. Menggunakan Daftar itu, Peta dapat dilingkarkan.
Lingkari Daftar menggunakan untuk masing-masing
atau
Lingkari Peta menggunakan untuk masing-masing
atau
sumber
sumber
Menggunakan versi Java yang lebih lama termasuk
Java 7
Anda dapat menggunakanforeach
loop sebagai berikut.Mengikuti adalah cara terbaru menggunakan
foreach
loop inJava 8
(loop Daftar dengan
forEach
ekspresi + lambda atau referensi metode)Untuk info lebih lanjut lihat tautan ini.
https://www.mkyong.com/java8/java-8-foreach-examples/
sumber
Inilah ekspresi yang setara.
sumber
Perhatikan juga bahwa menggunakan metode "foreach" dalam pertanyaan asli memang memiliki beberapa keterbatasan, seperti tidak dapat menghapus item dari daftar selama iterasi.
For-loop baru lebih mudah dibaca dan menghilangkan kebutuhan untuk iterator yang terpisah, tetapi hanya benar-benar dapat digunakan dalam pass iterasi read-only.
sumber
removeIf
mungkin alat yang tepatAlternatif untuk forEach untuk menghindari "untuk masing-masing" Anda:
Varian 1 (biasa):
Varian 2 (eksekusi paralel (lebih cepat)):
sumber
for(
formulir jika saya ingin memastikan utas yang sama digunakan. Saya suka menggunakan stream-form jika saya ingin mengizinkan eksekusi multithreaded.Ini menambah keindahan kode Anda dengan menghapus semua kekacauan perulangan dasar. Ini memberikan tampilan bersih ke kode Anda, dibenarkan di bawah ini.
for
Lingkaran normal :Gunakan untuk masing-masing:
untuk-masing-masing adalah konstruksi atas koleksi yang mengimplementasikan Iterator . Ingat itu, koleksi Anda harus menerapkan Iterator ; jika tidak, Anda tidak dapat menggunakannya dengan masing-masing.
Baris berikut dibaca sebagai " untuk setiap t TimerTask dalam daftar. "
Ada sedikit kemungkinan kesalahan dalam kasus untuk masing-masing. Anda tidak perlu khawatir tentang menginisialisasi iterator atau menginisialisasi penghitung lingkaran dan menghentikannya (di mana ada ruang untuk kesalahan).
sumber
Sebelum ke Java 8, Anda harus menggunakan yang berikut ini:
Namun, dengan diperkenalkannya Streams di Java 8 Anda dapat melakukan hal yang sama dalam sintaks yang jauh lebih sedikit. Misalnya, untuk Anda,
someList
Anda dapat melakukan:Anda dapat menemukan lebih banyak tentang stream di sini .
sumber
The foreach loop, added in Java 5 (also called the "enhanced for loop"), is equivalent to using a java.util.Iterator
Akan terlihat seperti ini. Sangat kekar.
Ada Langgan baik pada setiap dalam dokumentasi Sun .
sumber
Seperti yang dikatakan oleh begitu banyak jawaban yang baik, suatu objek harus mengimplementasikan
Iterable interface
jika ia ingin menggunakan afor-each
loop.Saya akan memposting contoh sederhana dan mencoba menjelaskan dengan cara yang berbeda cara
for-each
kerja loop.Contoh
for-each
loop:Kemudian, jika kita gunakan
javap
untuk mendekompilasi kelas ini, kita akan mendapatkan sampel bytecode ini:Seperti yang dapat kita lihat dari baris terakhir sampel, kompiler akan secara otomatis mengonversi penggunaan
for-each
kata kunci menjadi penggunaanIterator
pada waktu kompilasi. Itu mungkin menjelaskan mengapa objek, yang tidak mengimplementasikanIterable interface
, akan melemparException
ketika mencoba menggunakanfor-each
loop.sumber
The Java untuk setiap loop (alias ditingkatkan untuk loop) adalah versi sederhana dari untuk loop. Keuntungannya adalah bahwa ada lebih sedikit kode untuk ditulis dan lebih sedikit variabel untuk dikelola. Kelemahannya adalah bahwa Anda tidak memiliki kendali atas nilai langkah dan tidak ada akses ke indeks loop di dalam tubuh loop.
Mereka paling baik digunakan ketika nilai langkah adalah kenaikan sederhana 1 dan ketika Anda hanya perlu akses ke elemen loop saat ini. Misalnya, jika Anda perlu mengulang setiap elemen dalam array atau Koleksi tanpa mengintip ke depan atau di belakang elemen saat ini.
Tidak ada inisialisasi loop, tidak ada kondisi boolean dan nilai langkah implisit dan merupakan kenaikan sederhana. Inilah mengapa mereka dianggap jauh lebih sederhana daripada yang biasa untuk loop.
Ditingkatkan untuk loop, ikuti urutan eksekusi ini:
1) loop body
2) ulangi dari langkah 1 sampai seluruh larik atau koleksi telah dilintasi
Contoh - Bilangan Integer
Variabel currentValue memegang nilai saat ini dilingkarkan di dalam array intArray. Perhatikan bahwa tidak ada nilai langkah eksplisit - ini selalu merupakan kenaikan sebesar 1.
Usus besar dapat dianggap berarti "dalam". Jadi deklarasi loop yang disempurnakan menyatakan: loop over intArray dan menyimpan nilai int array saat ini dalam variabel currentValue.
Keluaran:
Contoh - String Array
Kita dapat menggunakan untuk-setiap loop untuk beralih di atas array string. Deklarasi loop menyatakan: loop over myStrings String array dan menyimpan nilai String saat ini dalam variabel currentString.
Keluaran:
Contoh - Daftar
Enhanced for loop juga dapat digunakan untuk beralih ke java.util.List sebagai berikut:
Deklarasi loop menyatakan: loop over myList List of Strings dan menyimpan nilai Daftar saat ini di variabel currentItem.
Keluaran:
Contoh - Set
Enhanced for loop juga dapat digunakan untuk beralih ke java.util.Set sebagai berikut:
Deklarasi loop menyatakan: loop over mySet Set of Strings dan menyimpan nilai Set saat ini dalam variabel currentItem. Perhatikan bahwa karena ini adalah Set, nilai-nilai String duplikat tidak disimpan.
Keluaran:
Sumber: Loops in Java - Ultimate Guide
sumber
sumber
Java untuk-setiap idiom hanya dapat diterapkan pada array atau objek bertipe * Iterable . Ungkapan ini tersirat karena benar-benar didukung oleh Iterator. Iterator diprogram oleh programmer dan sering menggunakan indeks integer atau node (tergantung pada struktur data) untuk melacak posisinya. Di atas kertas itu lebih lambat dari pada loop biasa, paling tidak untuk struktur "linier" seperti array dan Daftar tetapi memberikan abstraksi yang lebih besar.
sumber
Ini terlihat gila tapi hei itu berhasil
Ini bekerja. Sihir
sumber
Seperti banyak jawaban lain menyatakan dengan benar,
for
each
loop
itu hanya gula sintaksis di atas yang samafor
loop
dan kompiler menerjemahkannya ke yang sama untuk loop.javac (open jdk) memiliki saklar
-XD-printflat
, yang menghasilkan file java dengan semua gula sintaksis dihapus. perintah lengkapnya terlihat seperti iniJadi mari kita hapus gula sintaksis
Untuk menjawab pertanyaan ini, saya membuat file dan menulis dua versi
for
each
, satu denganarray
dan yang lain dengan alist
.java
file saya terlihat seperti ini.Ketika saya
compiled
file ini dengan switch di atas, saya mendapat output berikut.Anda dapat melihat bahwa bersama dengan gula sintaksis lainnya (Autoboxing) untuk setiap loop diubah menjadi loop sederhana.
sumber
Iterasikan semua objek dalam tabel Item.
sumber