Saya ingin membuat daftar opsi untuk tujuan pengujian. Pada awalnya, saya melakukan ini:
ArrayList<String> places = new ArrayList<String>();
places.add("Buenos Aires");
places.add("Córdoba");
places.add("La Plata");
Lalu, saya refactored kode sebagai berikut:
ArrayList<String> places = new ArrayList<String>(
Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));
Apakah ada cara yang lebih baik untuk melakukan ini?
java
collections
arraylist
initialization
Makarse
sumber
sumber
ArrasyList<String> places = ["Buenos Aires", "Córdoba", "La Plata"]
Jawaban:
Sebenarnya, mungkin cara "terbaik" untuk menginisialisasi
ArrayList
adalah metode yang Anda tulis, karena tidak perlu membuat yang baruList
dengan cara apa pun:Tangkapannya adalah bahwa ada sedikit pengetikan yang diperlukan untuk merujuk pada
list
instance itu.Ada beberapa alternatif, seperti membuat kelas dalam anonim dengan inisialisasi instance (juga dikenal sebagai "inisialisasi penjepit ganda"):
Namun, saya tidak terlalu menyukai metode itu karena apa yang Anda dapatkan pada akhirnya adalah subkelas
ArrayList
yang memiliki instance initializer, dan kelas itu dibuat hanya untuk membuat satu objek - yang sepertinya sedikit berlebihan bagi saya.Apa yang akan lebih baik adalah jika proposal Literals Pengumpulan untuk Project Coin diterima (itu dijadwalkan akan diperkenalkan di Jawa 7, tetapi kemungkinan besar tidak akan menjadi bagian dari Java 8.):
Sayangnya itu tidak akan membantu Anda di sini, karena ini akan menginisialisasi yang kekal
List
alih-alih sebuahArrayList
, dan lebih jauh lagi, itu belum tersedia, jika memang pernah ada.sumber
Akan lebih mudah jika Anda hanya mendeklarasikannya sebagai
List
- apakah harus menjadi ArrayList?Atau jika Anda hanya memiliki satu elemen:
Ini berarti yang
places
tidak dapat diubah (mencoba mengubahnya akan menyebabkanUnsupportedOperationException
pengecualian dilemparkan).Untuk membuat daftar yang dapat diubah yang merupakan beton,
ArrayList
Anda dapat membuatArrayList
dari daftar yang tidak dapat diubah:sumber
ArrayList
, akan lebih baik untuk mengubah deklarasiList
. Tentukan antarmuka, bukan implementasi.asList(...)
mengembalikan ukuran tetapList
yang meledak pada operasi bermutasi sepertiremove
danclear
, hal-hal yangList
diklaim mendukung kontrak. Bahkan jika Anda meninggalkan deklarasi sebagaiList
, Anda masih perlu menggunakanList l = new ArrayList(asList(...))
untuk mendapatkan objek yang tidak membuang pengecualian OperationNotSupported. Prinsip Pergantian Liskov siapa saja?remove
danclear
merupakan operasi opsionalList
, begituasList(...)
juga mengikuti kontrak. Tidak ada tempat OP mengatakan dia perlu menambahkan lebih banyak elemen nanti, contohnya adalah hanya dariList
yang perlu diinisialisasi dengan tiga elemen.Jawabannya sederhana
Di Java 9 atau lebih baru, setelah
List.of()
ditambahkan:Dengan Java 10 atau lebih baru, ini dapat disingkat dengan
var
kata kunci.Ini akan memberi Anda kekal
List
, jadi itu tidak bisa diubah.Apa yang Anda inginkan dalam banyak kasus di mana Anda melakukan pra-pengisian.
Java 8 atau sebelumnya:
Ini akan memberi Anda
List
didukung oleh array, sehingga tidak dapat mengubah panjang.Tapi Anda bisa menelepon
List.set
, jadi masih bisa berubah .Anda dapat membuat
Arrays.asList
lebih pendek dengan impor statis:Impor statis:
Yang disarankan oleh setiap IDE modern dan otomatis untuk Anda
Misalnya di IntelliJ IDEA Anda menekan
Alt+Enter
dan memilihStatic import method...
.Namun, saya tidak menyarankan untuk memperpendek
List.of
metodeof
, karena itu menjadi membingungkan.List.of
sudah cukup pendek dan membaca dengan baik.Menggunakan
Stream
sKenapa harus jadi
List
?Dengan Java 8 atau lebih baru Anda dapat menggunakan
Stream
yang lebih fleksibel:Anda dapat menggabungkan
Stream
:Atau Anda dapat beralih dari a
Stream
keList
:Tetapi lebih disukai, gunakan saja
Stream
tanpa mengumpulkannya untukList
.Jika Anda benar - benar membutuhkan
java.util.ArrayList
(Anda mungkin tidak.)
Mengutip JEP 269 (penekanan milik saya):
Jika Anda ingin keduanya menjadi pra-populasi
ArrayList
dan menambahkannya setelah itu (mengapa?), Gunakanatau di Java 8 atau sebelumnya:
atau menggunakan
Stream
:Tapi sekali lagi, lebih baik menggunakan
Stream
langsung daripada mengumpulkannya untukList
.Program untuk antarmuka, bukan implementasi
Anda mengatakan telah mendeklarasikan daftar sebagai
ArrayList
dalam kode Anda, tetapi Anda hanya boleh melakukannya jika Anda menggunakan beberapa anggotaArrayList
yang tidak ada dalamList
.Yang kemungkinan besar tidak Anda lakukan.
Biasanya Anda hanya harus mendeklarasikan variabel dengan antarmuka yang paling umum yang Anda akan digunakan (misalnya
Iterable
,Collection
atauList
), dan menginisialisasi mereka dengan pelaksanaan tertentu (misalnyaArrayList
,LinkedList
atauArrays.asList()
).Kalau tidak, Anda membatasi kode Anda ke jenis tertentu, dan akan lebih sulit untuk mengubah kapan pun Anda mau.
Misalnya, jika Anda melewati sebuah
ArrayList
kevoid method(...)
:Contoh lain akan selalu menyatakan variabel
InputStream
meskipun biasanya aFileInputStream
atau aBufferedInputStream
, karena suatu hari nanti Anda atau orang lain akan ingin menggunakan beberapa jenis lainInputStream
.sumber
Arrays.asList
adalah metode statis. Lihat docs.oracle.com/javase/1.5.0/docs/guide/language/…Jika Anda memerlukan daftar sederhana ukuran 1:
Jika Anda memerlukan daftar beberapa objek:
sumber
Dengan Jambu Anda dapat menulis:
Di Jambu ada juga konstruktor statis berguna lainnya. Anda dapat membacanya di sini .
sumber
java.util.Arrays
dengan,List<String> names = Arrays.asList("Beckah", "Sam", "Michael");
Literal kumpulan tidak berhasil masuk ke Java 8, tetapi dimungkinkan untuk menggunakan API Stream untuk menginisialisasi daftar dalam satu baris yang agak panjang:
Jika Anda perlu memastikan bahwa Anda
List
adalahArrayList
:sumber
Dengan java-9dan di atas, seperti yang disarankan dalam JEP 269: Convenience Factory Methods for Collections , ini dapat dicapai dengan menggunakan literal koleksi sekarang dengan -
Pendekatan serupa juga berlaku untuk
Map
-yang mirip dengan proposal Collection Literals seperti yang dinyatakan oleh @coobird. Lebih lanjut diklarifikasi dalam JEP juga -
Alternatif
Terkait: Apa gunanya Metode Convenience Factory yang terlalu banyak untuk Koleksi di Jawa 9
sumber
sumber
Collections.unmodifiableList(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"))
, yang menjadiunmodifiableList(asList("Buenos Aires", "Córdoba", "La Plata"))
dengan impor statis. Anda tidak memerlukan Google Collections untuk ini.ImmutableList
ke metode lain yang menggunakanList
, dan kemudian Anda kehilangan dokumentasi itu.Anda dapat membuat metode pabrik:
Tapi itu tidak jauh lebih baik daripada refactoring pertama Anda.
Untuk fleksibilitas yang lebih besar, ini dapat bersifat umum
sumber
Di Java 9 kita dapat dengan mudah menginisialisasi
ArrayList
dalam satu baris:atau
Pendekatan baru Java 9 ini memiliki banyak keunggulan dibandingkan yang sebelumnya:
Lihat posting ini untuk lebih jelasnya -> Apa perbedaan antara List.of dan Arrays.asList?
sumber
Tentang cara paling ringkas untuk melakukan ini adalah:
sumber
Cukup gunakan kode di bawah ini sebagai berikut.
sumber
Dengan Eclipse Collections Anda dapat menulis yang berikut ini:
Anda juga bisa lebih spesifik tentang jenis dan apakah mereka bisa berubah atau tidak berubah.
Anda juga dapat melakukan hal yang sama dengan Set dan Tas:
Catatan: Saya pengendara untuk Eclipse Collections.
sumber
Ini cara lain:
sumber
(Seharusnya komentar, tapi terlalu panjang, balasan begitu baru) Seperti yang disebutkan orang lain,
Arrays.asList
metode ini berukuran tetap, tetapi itu bukan satu-satunya masalah. Itu juga tidak menangani warisan dengan sangat baik. Misalnya, Anda memiliki yang berikut:Hasil di atas dalam kesalahan kompiler, karena
List<B>
(yang dikembalikan oleh Arrays.asList) bukan subkelasList<A>
, meskipun Anda bisa menambahkan Objek tipe B keList<A>
objek. Untuk menyiasati ini, Anda perlu melakukan sesuatu seperti:Ini mungkin cara terbaik untuk melakukan ini, esp. jika Anda memerlukan daftar tanpa batas atau perlu menggunakan warisan.
sumber
Anda dapat menggunakan pernyataan di bawah ini:
Cuplikan Kode:
sumber
letters = Arrays.asList(new String[]{"A", "B", "C"});
Seperti yang Tom katakan :
Tetapi karena Anda mengeluh ingin ArrayList, Anda harus terlebih dahulu tahu bahwa ArrayList adalah subkelas Daftar dan Anda bisa menambahkan baris ini:
Meskipun, itu mungkin membuat Anda mengeluh tentang 'kinerja'.
Dalam hal itu tidak masuk akal bagi saya, mengapa, karena daftar Anda sudah ditentukan sebelumnya tidak didefinisikan sebagai array (karena ukurannya diketahui pada saat inisialisasi). Dan jika itu pilihan bagi Anda:
Jika Anda tidak peduli dengan perbedaan kinerja kecil maka Anda juga dapat menyalin array ke ArrayList dengan sangat sederhana:
Oke, tetapi di masa depan Anda perlu sedikit lebih dari sekadar nama tempat, Anda juga memerlukan kode negara. Dengan anggapan ini masih merupakan daftar yang telah ditentukan yang tidak akan pernah berubah selama waktu berjalan, maka pantas untuk menggunakan suatu
enum
set, yang akan membutuhkan kompilasi ulang jika daftar tersebut perlu diubah di masa mendatang.akan menjadi:
Enum's memiliki
values
metode statis yang mengembalikan array yang berisi semua nilai enum dalam urutan yang dideklarasikan, misalnya:Dalam hal ini saya kira Anda tidak perlu ArrayList Anda.
PS Randyaa mendemonstrasikan cara bagus lain menggunakan metode utilitas statis Collections.addAll .
sumber
Java 9 memiliki metode berikut untuk membuat daftar yang tidak dapat diubah :
yang mudah diadaptasi untuk membuat daftar yang bisa berubah, jika diperlukan:
Metode serupa tersedia untuk
Set
danMap
.sumber
sumber
Ya dengan bantuan Array Anda dapat menginisialisasi daftar array dalam satu baris,
sumber
Anda dapat menggunakan
StickyList
dari Cactoos :sumber
Coba dengan baris kode ini:
sumber
Di Jawa, Anda tidak bisa melakukannya
Seperti yang telah ditunjukkan, Anda harus melakukan inisialisasi penjepit ganda:
Tetapi ini mungkin memaksa Anda untuk menambahkan anotasi
@SuppressWarnings("serial")
atau membuat UUID serial yang menjengkelkan. Juga sebagian besar pembuat kode akan membuka itu menjadi beberapa pernyataan / baris.Atau Anda bisa melakukannya
tapi kemudian Anda mungkin ingin melakukan
@SuppressWarnings("unchecked")
.Juga menurut javadoc Anda harus dapat melakukan ini:
Tapi saya tidak bisa membuatnya untuk dikompilasi dengan JDK 1.6.
sumber
Jika Anda perlu memiliki daftar satu item !
Koleksi adalah dari paket java.util .
sumber
Cara terbaik untuk melakukannya:
Cukup buat fungsi yang dapat memiliki elemen sebanyak yang Anda inginkan dan panggil untuk menambahkannya dalam satu baris.
sumber
Object
.Berikut ini kode dari AbacusUtil
Deklarasi : Saya pengembang AbacusUtil.
sumber
Bagi saya Arrays.asList () adalah yang terbaik dan nyaman. Saya selalu suka menginisialisasi seperti itu. Jika Anda seorang pemula dalam Koleksi Java maka saya ingin Anda merujuk inisialisasi ArrayList
sumber
add()
metode?Mengapa tidak membuat fungsi utilitas sederhana yang melakukan ini?
"
ll
" singkatan dari "daftar literal".sumber
Menariknya tidak ada satu-liner dengan metode kelebihan beban lainnya
Stream::collect
terdaftarsumber
Sebenarnya, dimungkinkan untuk melakukannya dalam satu baris:
sumber