Apakah ada cara untuk menginisialisasi Java HashMap seperti ini ?:
Map<String,String> test =
new HashMap<String, String>{"test":"test","test":"test"};
Apa yang akan menjadi sintaks yang benar? Saya belum menemukan apa pun mengenai hal ini. Apakah ini mungkin? Saya mencari cara terpendek / tercepat untuk meletakkan beberapa nilai "final / statis" di peta yang tidak pernah berubah dan diketahui sebelumnya saat membuat Peta.
Jawaban:
Semua versi
Jika Anda membutuhkan hanya satu entri: Ada
Collections.singletonMap("key", "value")
.Untuk Java Versi 9 atau lebih tinggi:
Ya, ini mungkin sekarang. Di Jawa 9 beberapa metode pabrik telah ditambahkan yang menyederhanakan pembuatan peta:
Dalam contoh di atas keduanya
test
dantest2
akan sama, hanya dengan berbagai cara mengekspresikan Peta. TheMap.of
Metode didefinisikan sampai elemen sepuluh di peta, sedangkanMap.ofEntries
metode tidak akan memiliki batas tersebut.Perhatikan bahwa dalam hal ini peta yang dihasilkan akan menjadi peta yang tidak berubah. Jika Anda ingin peta dapat diubah, Anda dapat menyalinnya lagi, misalnya menggunakan
mutableMap = new HashMap<>(Map.of("a", "b"));
(Lihat juga JEP 269 dan Javadoc )
Untuk versi Java hingga 8:
Tidak, Anda harus menambahkan semua elemen secara manual. Anda dapat menggunakan penginisialisasi dalam subkelas anonim untuk membuat sintaks sedikit lebih pendek:
Namun, subclass anonim mungkin memperkenalkan perilaku yang tidak diinginkan dalam beberapa kasus. Ini termasuk misalnya:
Menggunakan fungsi untuk inisialisasi juga akan memungkinkan Anda untuk menghasilkan peta dalam penginisialisasi, tetapi menghindari efek samping yang buruk:
sumber
Collections.singletonMap()
:)entry
didokumentasikan?Ini satu arah.
Namun, Anda harus berhati-hati dan memastikan bahwa Anda memahami kode di atas (ini menciptakan kelas baru yang diwarisi dari HashMap). Karenanya, Anda harus membaca lebih lanjut di sini: http://www.c2.com/cgi/wiki?DoubleBraceInisialisasi , atau cukup gunakan Guava:
sumber
Jika Anda membiarkan libs pihak ke-3, Anda dapat menggunakan Jambu 's ImmutableMap untuk mencapai literal seperti singkatnya:
Ini berfungsi hingga 5 pasangan kunci / nilai , jika tidak Anda dapat menggunakan pembuatnya :
sumber
Tidak ada cara langsung untuk melakukan ini - Java tidak memiliki literal Peta (belum - saya pikir mereka diusulkan untuk Java 8).
Beberapa orang menyukai ini:
Ini menciptakan subclass anonim dari HashMap, yang penginisiasinya instan menempatkan nilai-nilai ini. (Omong-omong, peta tidak dapat memuat dua kali nilai yang sama, put kedua Anda akan menimpa yang pertama. Saya akan menggunakan nilai yang berbeda untuk contoh berikutnya.)
Cara normal adalah ini (untuk variabel lokal):
Jika
test
peta Anda adalah variabel instan, masukkan inisialisasi ke konstruktor atau inisialisasi instance:Jika
test
peta Anda adalah variabel kelas, letakkan inisialisasi dalam penginisialisasi statis:Jika Anda ingin peta Anda tidak pernah berubah, Anda harus setelah inisialisasi membungkus peta Anda dengan
Collections.unmodifiableMap(...)
. Anda dapat melakukan ini di penginisialisasi statis juga:(Saya tidak yakin apakah Anda sekarang dapat membuat
test
final ... coba dan laporkan di sini.)sumber
sumber
HashMap
ke dalam subkelas ini. Ini hanya dapat berfungsi jika Anda benar-benar menyediakannya. (Dengan HashMap baru (kosong), argumen tipe tidak relevan.)Alternatif, menggunakan kelas Java 7 dan varargs polos: buat kelas
HashMapBuilder
dengan metode ini:Gunakan metode seperti ini:
sumber
tl; dr
Gunakan
Map.of…
metode di Java 9 dan yang lebih baru.Map.of
Java 9 menambahkan serangkaian
Map.of
metode statis untuk melakukan apa yang Anda inginkan: Buat InstantiateMap
menggunakan sintaks literal .Peta (kumpulan entri) tidak dapat diubah, sehingga Anda tidak dapat menambah atau menghapus entri setelah membuat instance. Juga, kunci dan nilai setiap entri tidak berubah, tidak dapat diubah. Lihat Javadoc untuk aturan lain, seperti tidak ada NULL diizinkan, tidak ada kunci duplikat diizinkan, dan urutan iterasi pemetaan adalah arbitrer.
Mari kita lihat metode-metode ini, menggunakan beberapa sampel data untuk peta hari-minggu ke seseorang yang kita harapkan akan bekerja pada hari itu.
Map.of()
Map.of
menciptakan yang kosongMap
. Tidak dapat dimodifikasi, sehingga Anda tidak dapat menambahkan entri. Berikut adalah contoh peta seperti itu, kosong tanpa entri.Map.of( … )
Map.of( k , v , k , v , …)
ada beberapa metode yang mengambil 1 hingga 10 pasangan nilai kunci. Ini adalah contoh dari dua entri.Map.ofEntries( … )
Map.ofEntries( Map.Entry , … )
mengambil sejumlah objek yang mengimplementasikanMap.Entry
antarmuka. Java bundel dua kelas mengimplementasikan antarmuka itu, satu bisa berubah, yang lainnya tidak berubah:AbstractMap.SimpleEntry
,AbstractMap.SimpleImmutableEntry
. Tetapi kita tidak perlu menentukan kelas konkret. Kita hanya perlu memanggilMap.entry( k , v )
metode, meneruskan kunci dan nilai kita, dan kita mendapatkan kembali objek dari beberapaMap.Entry
antarmuka implementasi kelas .Map.copyOf
Java 10 menambahkan metode ini
Map.copyOf
. Lewati peta yang ada, dapatkan kembali salinan peta itu yang tidak berubah.Catatan
Perhatikan bahwa urutan iterator peta yang dihasilkan melalui
Map.of
yang tidak dijamin. Entri memiliki perintah sewenang-wenang. Jangan menulis kode berdasarkan urutan yang terlihat, karena dokumentasi memperingatkan pesanan dapat berubah.Perhatikan bahwa semua
Map.of…
metode ini mengembalikan aMap
dari kelas yang tidak ditentukan . Kelas beton yang mendasari bahkan dapat bervariasi dari satu versi Java ke yang lain. Anonimitas ini memungkinkan Java untuk memilih dari berbagai implementasi, apa pun yang secara optimal sesuai dengan data khusus Anda. Misalnya, jika kunci Anda berasal dari enum , Java mungkin menggunakanEnumMap
bawah.sumber
Anda dapat membuat
Map.of
metode Anda sendiri (yang hanya tersedia di Java 9 dan lebih tinggi) dengan mudah dalam 2 cara mudahBuat dengan sejumlah parameter yang ditetapkan
Contoh
Jadikan menggunakan Daftar
Anda juga dapat membuatnya menggunakan daftar, alih-alih membuat banyak metode untuk serangkaian parameter tertentu.
Contoh
Catatan Tidak disarankan untuk menggunakan ini untuk semuanya karena ini membuat kelas anonim setiap kali Anda menggunakan ini.
sumber
JAWA 8
Di java 8 Anda juga memiliki kemungkinan menggunakan
Streams/Collectors
untuk melakukan pekerjaan.Ini memiliki keuntungan karena tidak membuat kelas Anonim.
Perhatikan bahwa impor adalah:
Tentu saja, seperti disebutkan dalam jawaban lain, di java 9 dan seterusnya Anda memiliki cara yang lebih sederhana untuk melakukan hal yang sama.
sumber
Sayangnya, menggunakan varargs jika jenis kunci dan nilai tidak sama tidak masuk akal karena Anda harus menggunakan
Object...
dan kehilangan keamanan jenis sepenuhnya. Jika Anda selalu ingin membuat misalnya aMap<String, String>
, tentu saja atoMap(String... args)
mungkin saja, tetapi tidak terlalu cantik karena akan mudah untuk mencampur kunci dan nilai, dan sejumlah ganjil argumen akan tidak valid.Anda bisa membuat sub-kelas dari HashMap yang memiliki metode seperti rantai
dan menggunakannya seperti
new ChainableMap<String, Object>().set("a", 1).set("b", "foo")
Pendekatan lain adalah dengan menggunakan pola pembangun umum:
dan menggunakannya seperti
new MapBuilder<String, Object>().put("a", 1).put("b", "foo").build();
Namun, solusi yang saya gunakan sekarang dan kemudian menggunakan varargs dan
Pair
kelas:Map<String, Object> map = Maps.of(Pair.create("a", 1), Pair.create("b", "foo");
Kata-kata
Pair.create()
yang agak mengganggu saya sedikit, tetapi ini bekerja cukup baik. Jika Anda tidak keberatan impor statis, tentu saja Anda dapat membuat pembantu:Map<String, Object> map = Maps.of(p("a", 1), p("b", "foo");
(Alih-alih
Pair
bisa dibayangkan menggunakanMap.Entry
, tapi karena itu antarmuka, ini membutuhkan kelas implementasi dan / atau metode pabrik pembantu. Ini juga tidak dapat diubah, dan mengandung logika lain yang tidak berguna untuk tugas ini.)sumber
Anda dapat menggunakan Streams In Java 8 (ini adalah exmaple dari Set):
Ref: https://www.baeldung.com/java-double-brace-initialisation
sumber
Jika Anda hanya perlu menempatkan satu pasangan nilai kunci, Anda dapat menggunakan Collections.singletonMap (kunci, nilai);
sumber