Seperti yang orang lain katakan, Iterable dapat dipanggil beberapa kali, mengembalikan Iterator baru pada setiap panggilan; Iterator hanya digunakan sekali. Jadi mereka saling berhubungan, tetapi melayani tujuan yang berbeda. Namun, frustrasi, metode "kompak untuk" hanya bekerja dengan iterable.
Apa yang akan saya jelaskan di bawah ini adalah salah satu cara untuk mendapatkan yang terbaik dari kedua dunia - mengembalikan sebuah Iterable (untuk sintaksis yang lebih baik) bahkan ketika urutan data yang mendasarinya adalah sekali saja.
Caranya adalah dengan mengembalikan implementasi anterable dari Iterable yang sebenarnya memicu pekerjaan. Jadi alih-alih melakukan pekerjaan yang menghasilkan urutan satu kali dan kemudian mengembalikan Iterator lebih dari itu, Anda mengembalikan Iterable yang, setiap kali diakses, mengulangi pekerjaan. Itu mungkin tampak sia-sia, tetapi sering kali Anda hanya akan memanggil Iterable sekali saja, dan bahkan jika Anda menyebutnya berkali-kali, itu masih memiliki semantik yang masuk akal (tidak seperti pembungkus sederhana yang membuat Iterator "terlihat seperti" yang Iterable, ini akan menang ' t gagal jika digunakan dua kali).
Misalnya, saya memiliki DAO yang menyediakan serangkaian objek dari database, dan saya ingin memberikan akses ke sana melalui iterator (mis. Untuk menghindari membuat semua objek dalam memori jika tidak diperlukan). Sekarang saya hanya bisa mengembalikan iterator, tetapi itu membuat menggunakan nilai yang dikembalikan dalam satu lingkaran jelek. Jadi alih-alih saya membungkus semuanya dalam anon Iterable:
class MetricDao {
...
/**
* @return All known metrics.
*/
public final Iterable<Metric> loadAll() {
return new Iterable<Metric>() {
@Override
public Iterator<Metric> iterator() {
return sessionFactory.getCurrentSession()
.createQuery("from Metric as metric")
.iterate();
}
};
}
}
ini kemudian dapat digunakan dalam kode seperti ini:
class DaoUser {
private MetricDao dao;
for (Metric existing : dao.loadAll()) {
// do stuff here...
}
}
yang memungkinkan saya menggunakan compact untuk loop sambil tetap menjaga penggunaan memori tambahan.
Pendekatan ini "malas" - pekerjaan tidak dilakukan ketika Iterable diminta, tetapi hanya nanti ketika isinya diulangi - dan Anda perlu menyadari konsekuensi dari itu. Dalam contoh dengan DAO itu berarti mengulangi hasil dalam transaksi basis data.
Jadi ada berbagai peringatan, tetapi ini masih bisa menjadi ungkapan yang berguna dalam banyak kasus.