Saya memiliki Array primitif, misalnya untuk int, int [] foo. Mungkin yang berukuran kecil, atau tidak.
int foo[] = {1,2,3,4,5,6,7,8,9,0};
Apa cara terbaik untuk membuatnya Iterable<Integer>
?
Iterable<Integer> fooBar = convert(foo);
Catatan:
Tolong jangan menjawab menggunakan loop (kecuali Anda dapat memberikan penjelasan yang baik tentang bagaimana kompiler melakukan sesuatu yang pintar tentang mereka?)
Perhatikan juga itu
int a[] = {1,2,3};
List<Integer> l = Arrays.asList(a);
Bahkan tidak akan mengkompilasi
Type mismatch: cannot convert from List<int[]> to List<Integer>
Juga periksa Mengapa array tidak dapat ditugaskan untuk Iterable? sebelum menjawab.
Juga, jika Anda menggunakan beberapa perpustakaan (mis. Jambu), tolong jelaskan mengapa ini adalah yang terbaik. (Karena dari Google bukan jawaban lengkap: P)
Terakhir, karena tampaknya ada pekerjaan rumah tentang itu, hindari memposting kode pekerjaan rumah.
Jawaban:
Meskipun Anda perlu menggunakan
Integer
array (bukanint
array) agar ini berfungsi.Untuk primitif, Anda dapat menggunakan jambu biji:
Untuk Java8: (dari jawaban Jin Kwon)
sumber
int
, bukanInteger
2)List
sudahIterable
jadi baris ketiga tidak ada gunanya.hanya 2 sen saya:
sumber
Iterator<Character>
dariString
. Menerapkan milik Anda sendiriIterator
sepertinya satu-satunya cara untuk menghindari perulangan yang tidak perlu melalui semua nilai untuk mengkonversi dari tipe objek ke tipe primitif (misalnya melalui GuavaInts.asList()
), hanya untuk bisa mendapatkanIterator
dariList
yang telah dibuat.Dengan Java 8, Anda dapat melakukan ini.
sumber
Guava menyediakan adaptor yang Anda inginkan sebagai Int.asList () . Ada yang setara untuk setiap tipe primitif di kelas terkait, misalnya,
Booleans
untukboolean
, dll.Saran di atas untuk digunakan
Arrays.asList
tidak akan berfungsi, bahkan jika mereka dikompilasi karena Anda mendapatkanIterator<int[]>
daripadaIterator<Integer>
. Apa yang terjadi adalah bahwa alih-alih membuat daftar yang didukung oleh array Anda, Anda membuat daftar 1-elemen array, yang berisi array Anda.sumber
Saya memiliki masalah yang sama dan menyelesaikannya seperti ini:
Iterator itu sendiri malas
UnmodifiableIterator
tapi itulah yang saya butuhkan.sumber
Di Java 8 atau lebih baru,
Iterable
adalah antarmuka fungsional yang kembaliIterator
. Jadi kamu bisa melakukan ini.sumber
Pertama-tama, saya hanya bisa setuju bahwa
Arrays.asList(T...)
ini jelas merupakan solusi terbaik untuk tipe Wrapper atau array dengan tipe data non-primitif. Metode ini memanggil konstruktorAbstractList
implementasi statis privat sederhana diArrays
kelas yang pada dasarnya menyimpan referensi array yang diberikan sebagai bidang dan mensimulasikan daftar dengan menimpa metode yang diperlukan.Jika Anda dapat memilih antara tipe primtive atau tipe Wrapper untuk array Anda, saya akan menggunakan tipe Wrapper untuk situasi seperti itu tetapi tentu saja, itu tidak selalu berguna atau diperlukan. Hanya akan ada dua kemungkinan yang dapat Anda lakukan:
1) Anda dapat membuat kelas dengan metode statis untuk setiap array tipe data primitif (
boolean, byte, short, int, long, char, float, double
mengembalikanIterable<
WrapperType>
. Metode ini akan menggunakan kelas anonimIterator
(selainIterable
) yang diizinkan mengandung referensi argumen metode yang terdiri (misalnya,int[]
) sebagai bidang untuk mengimplementasikan metode.-> Pendekatan ini performan dan menghemat memori Anda (kecuali untuk memori metode yang baru dibuat, meskipun, menggunakan
Arrays.asList()
akan mengambil memori dengan cara yang sama)2) Karena array tidak memiliki metode (seperti yang dibaca di samping Anda ditautkan) mereka tidak dapat memberikan
Iterator
contoh juga. Jika Anda benar-benar terlalu malas untuk menulis kelas baru, Anda harus menggunakan contoh dari kelas yang sudah ada yang mengimplementasikanIterable
karena tidak ada jalan lain selain instantiatingIterable
atau subtipe.Cara HANYA untuk membuat implementasi turunan Koleksi yang ada
Iterable
adalah menggunakan loop (kecuali Anda menggunakan kelas anonim seperti yang dijelaskan di atas) atau Anda membuat instanceIterable
kelas pelaksana yang konstruktornya memungkinkan array tipe primtive (karenaObject[]
tidak memungkinkan array dengan elemen tipe primitif) tetapi sejauh yang saya tahu, Java API tidak menampilkan kelas seperti itu.Alasan untuk perulangan dapat dijelaskan dengan mudah:
untuk setiap Koleksi yang Anda butuhkan Objek dan tipe data primtive bukan objek. Objek jauh lebih besar dari tipe primitif sehingga mereka membutuhkan data tambahan yang harus dihasilkan untuk setiap elemen dari array tipe primitif. Itu berarti jika dua cara tiga (menggunakan
Arrays.asList(T...)
atau menggunakan Koleksi yang ada) memerlukan agregat objek, Anda harus membuat untuk setiap nilai primitif dari Andaint[]
Array objek pembungkus. Cara ketiga akan menggunakan array apa adanya dan menggunakannya dalam kelas anonim karena saya pikir itu lebih disukai karena kinerja yang cepat.Ada juga strategi ketiga menggunakan
Object
argumen as untuk metode di mana Anda ingin menggunakan array atauIterable
dan akan membutuhkan pemeriksaan tipe untuk mengetahui tipe argumen yang dimiliki, namun saya tidak akan merekomendasikannya sama sekali karena Anda biasanya perlu pertimbangkan bahwa Object tidak selalu tipe yang diperlukan dan Anda perlu kode terpisah untuk kasus-kasus tertentu.Kesimpulannya, ini adalah kesalahan sistem Generic Type bermasalah dari Java yang tidak memungkinkan untuk menggunakan tipe primitif sebagai tipe generik yang akan menghemat banyak kode hanya dengan menggunakan
Arrays.asList(T...)
. Jadi Anda perlu memprogram untuk setiap tipe array primitif, Anda perlu, metode seperti itu (yang pada dasarnya tidak membuat perbedaan pada memori yang digunakan oleh program C ++ yang akan membuat untuk setiap argumen tipe yang digunakan sebagai metode terpisah.sumber
Anda dapat menggunakan
IterableOf
dari Cactoos :Kemudian, Anda dapat mengubahnya menjadi daftar menggunakan
ListOf
:Atau sederhananya:
sumber
Sementara jawaban yang serupa sudah semacam diposkan, saya pikir alasan untuk menggunakan PrimitiveIterator baru. Sebenarnya tidak jelas. Solusi yang baik adalah dengan menggunakan Java 8 PrimitiveIterator karena ini khusus untuk tipe int primitif (dan menghindari penalti tinju / unboxing tambahan):
Ref: https://doc.bccnsoft.com/docs/jdk8u12-docs/api/java/util/PrimitiveIterator.OfInt.html
sumber
Dalam java8, aliran IntSteam dapat dikotakkan ke aliran Integer.
Saya pikir masalah kinerja berdasarkan ukuran array.
sumber