Dalam aplikasi saya, saya menggunakan perpustakaan pihak ke-3 (Data Spring untuk MongoDB tepatnya).
Metode perpustakaan ini kembali Iterable<T>
, sedangkan kode saya yang lain mengharapkan Collection<T>
.
Apakah ada metode utilitas di suatu tempat yang akan membiarkan saya dengan cepat mengkonversi satu ke yang lain? Saya ingin menghindari membuat banyak foreach
loop dalam kode saya untuk hal yang sangat sederhana.
java
collections
Ula Krukar
sumber
sumber
Jawaban:
Dengan Guava Anda dapat menggunakan Lists.newArrayList (Iterable) atau Sets.newHashSet (Iterable) , di antara metode serupa lainnya. Ini tentu saja akan menyalin semua elemen ke dalam memori. Jika itu tidak dapat diterima, saya pikir kode Anda yang berfungsi dengan ini harus mengambil
Iterable
alihCollection
. Jambu biji juga terjadi untuk memberikan metode yang nyaman untuk melakukan hal-hal yang dapat Anda lakukan padaCollection
menggunakanIterable
(sepertiIterables.isEmpty(Iterable)
atauIterables.contains(Iterable, Object)
), tetapi implikasi kinerja lebih jelas.sumber
Lists.newArrayList(Iterable).clear()
operasi waktu linier atau konstan?Collection
salah satu tidak dapat diimplementasikan untuk tampilanIterable
atau tidak akan efisien, tidak masuk akal bagi saya untuk melakukan itu.Iterables.concat()
tetapi itu memberiIterable
, bukanCollection
:(Iterables.concat()
. Jawaban yang lebih lama memberiCollection
... Saya bertanya-tanya mengapa ini tidak lebih umum didukung?Di JDK 8+, tanpa menggunakan lib tambahan:
Sunting: Yang di atas adalah untuk
Iterator
. Jika Anda berurusan denganIterable
,sumber
iterable.forEach(target::add);
Anda dapat menulis metode utilitas Anda sendiri untuk ini juga:
sumber
Iterable
menjadiCollection
satu-satunya masalah, saya lebih suka pendekatan ini daripada mengimpor perpustakaan koleksi-pihak ke-3 yang besar.Solusi ringkas dengan Java 8 menggunakan
java.util.stream
:sumber
IteratorUtils
daricommons-collections
IteratorUtils.toList()
menggunakan iterator dalam mode Java 5 pra untuk menambahkan elemen satu per satu ke daftar yang baru dibuat. Sederhana dan mungkin tercepat, tetapi menambahkan 734 kB ke biner Anda dan Anda bisa melakukannya sendiri jika Anda menemukan metode ini sebagai yang terbaik.IteratorUtils
fromcommons-collections
dapat membantu (meskipun mereka tidak mendukung obat generik dalam versi stabil terbaru 3.2.1):Versi 4.0 (yang ada di SNAPSHOT saat ini) mendukung obat generik dan Anda dapat menyingkirkannya
@SuppressWarnings
.Pembaruan: Periksa
IterableAsList
dari Cactoos .sumber
IterableUtils.toList(Iterable)
, yang merupakan metode kenyamanan dan penggunaan diIteratorUtils
bawah tenda, tetapi juga null-safe (tidak sepertiIteratorUtils.toList
).Dari CollectionUtils :
Berikut adalah sumber lengkap dari metode utilitas ini:
sumber
Lists.newArrayList(someIterable).clear()
operasi waktu linier atau konstan?addAll
, seperti namanya, itu menyalin nilai iterator satu demi satu; itu membuat salinan daripada tampilan.CollectionUtils
untuk melewati pembuatan koleksi di baris tambahan.Sementara itu, jangan lupa bahwa semua koleksi terbatas, sementara Iterable tidak punya janji apa pun. Jika sesuatu Iterable Anda bisa mendapatkan Iterator dan hanya itu.
akan diperluas ke:
it.hasNext () tidak diharuskan untuk mengembalikan false. Dengan demikian dalam kasus umum Anda tidak dapat berharap untuk dapat mengkonversi setiap Iterable ke Koleksi. Misalnya Anda dapat mengulangi semua bilangan alami positif, beralih pada sesuatu dengan siklus di dalamnya yang menghasilkan hasil yang sama berulang-ulang, dll.
Jika tidak: Jawaban Atrey cukup baik.
sumber
Saya menggunakan
FluentIterable.from(myIterable).toList()
banyak.sumber
Ini bukan jawaban untuk pertanyaan Anda tetapi saya yakin ini adalah solusi untuk masalah Anda. Antarmuka
org.springframework.data.repository.CrudRepository
memang memiliki metode yang mengembalikanjava.lang.Iterable
tetapi Anda tidak harus menggunakan antarmuka ini. Alih-alih menggunakan sub antarmuka, dalam kasus Andaorg.springframework.data.mongodb.repository.MongoRepository
. Antarmuka ini memiliki metode yang mengembalikan objek bertipejava.util.List
.sumber
Saya menggunakan utilitas khusus saya untuk melemparkan Koleksi yang ada jika tersedia.
Utama:
Idealnya di atas akan menggunakan ImmutableList, tetapi ImmutableCollection tidak mengizinkan nol yang dapat memberikan hasil yang tidak diinginkan.
Tes:
Saya menerapkan utilitas serupa untuk semua subtipe Koleksi (Set, Daftar, dll). Saya pikir ini sudah menjadi bagian dari Jambu Biji, tetapi saya belum menemukannya.
sumber
Segera setelah Anda menelepon
contains
,containsAll
,equals
,hashCode
,remove
,retainAll
,size
atautoArray
, Anda harus melintasi elemen pula.Jika Anda sesekali hanya memanggil metode seperti
isEmpty
atauclear
saya kira Anda akan lebih baik dengan membuat koleksi dengan malas. Misalnya, Anda dapat memiliki dukunganArrayList
untuk menyimpan elemen yang sebelumnya di-iterasi.Saya tidak tahu ada kelas seperti itu di perpustakaan mana pun, tetapi itu harus menjadi latihan yang cukup sederhana untuk menulis.
sumber
Di Java 8 Anda dapat melakukan ini untuk menambahkan semua elemen dari
Iterable
keCollection
dan mengembalikannya:Terinspirasi oleh jawaban @Afreys.
sumber
Karena RxJava adalah palu dan ini terlihat seperti paku, Anda dapat melakukannya
sumber
Berikut ini SSCCE untuk cara hebat melakukannya di Java 8
sumber
Aku datang di situasi yang sama ketika mencoba untuk mengambil sebuah
List
dariProject
s, daripada defaultIterable<T> findAll()
dideklarasikan dalamCrudRepository
interface. Jadi, diProjectRepository
antarmuka saya (yang memanjang dariCrudRepository
), saya hanya menyatakanfindAll()
metode untuk mengembalikanList<Project>
bukanIterable<Project>
.Ini adalah solusi paling sederhana, saya pikir, tanpa memerlukan logika konversi atau penggunaan perpustakaan eksternal.
sumber
Dua komentar
sumber
Coba
StickyList
dari Cactoos :sumber
Saya tidak melihat solusi satu baris sederhana tanpa dependensi. Saya menggunakan sederhana
sumber
Anda dapat menggunakan pabrik Eclipse Collections :
Anda juga dapat mengonversi
Iterable
ke aLazyIterable
dan menggunakan metode konverter atau API lain yang tersedia yang tersedia.Semua
Mutable
tipe di atas memanjangjava.util.Collection
.Catatan: Saya pengendara untuk Eclipse Collections.
sumber