Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?
java.util.Properties
adalah implementasi dari java.util.Map
, dan java.util.HashMap
konstruktor menerima Map
parameter tipe. Jadi, mengapa harus diubah secara eksplisit?
Hashtable<Object, Object>
, bahkan hal-hal yang bukan string - bahkan kunci yang bukan string.Cara efisien untuk melakukannya hanya dengan mentransmisikan ke Peta umum sebagai berikut:
Properties props = new Properties(); Map<String, String> map = (Map)props;
Ini akan mengubah a
Map<Object, Object>
menjadi Peta mentah, yang "ok" untuk kompilator (hanya peringatan). Setelah kita memiliki mentahMap
itu akan dilemparkanMap<String, String>
yang juga akan menjadi "ok" (peringatan lain). Anda dapat mengabaikannya dengan anotasi@SuppressWarnings({ "unchecked", "rawtypes" })
Ini akan berhasil karena di JVM objek tidak benar-benar memiliki tipe generik. Jenis generik hanyalah trik yang memverifikasi berbagai hal pada waktu kompilasi.
Jika beberapa kunci atau nilai bukan String, ini akan menghasilkan
ClassCastException
kesalahan. Dengan arusProperties
implementasi ini sangat tidak mungkin terjadi, selama Anda tidak menggunakan metode panggilan bisa berubah dari superHashtable<Object,Object>
dariProperties
.Jadi, jika tidak melakukan hal-hal buruk dengan contoh Properti Anda, ini adalah cara yang tepat.
sumber
Map
contoh setidaknya pada kode yang diberikan, jadi saya pikir inilah yang dia butuhkanAnda bisa menggunakan Google Guava:
com.google.common.collect.Maps.fromProperties (Properti)
sumber
Bagaimana dengan ini?
Map properties = new Properties(); Map<String, String> map = new HashMap<String, String>(properties);
Akan menyebabkan peringatan, tetapi bekerja tanpa iterasi.
sumber
Map<Object, Object>
, ini adalahMap
argumen (tipe mentah). Jawaban ini benar(Map<String, String>) ((Map) properties)
Cara Java 8:
sumber
Properties
mengimplementasikanMap<Object, Object>
- tidakMap<String, String>
.Anda mencoba memanggil konstruktor ini:
public HashMap(Map<? extends K,? extends V> m)
... dengan
K
danV
keduanya sebagaiString
.Tapi
Map<Object, Object>
bukanMap<? extends String, ? extends String>
... itu bisa berisi kunci dan nilai non-string.Ini akan berhasil:
Map<Object, Object> map = new HashMap<Object, Object>();
... tapi itu tidak akan berguna bagi Anda.
Pada dasarnya,
Properties
seharusnya tidak pernah dijadikan subclass dariHashTable
... itulah masalahnya. Sejak v1, itu selalu dapat menyimpan kunci dan nilai non-String, meskipun itu bertentangan dengan maksudnya. Jika komposisi telah digunakan sebagai gantinya, API hanya bisa bekerja dengan kunci / nilai string, dan semuanya akan berjalan dengan baik.Anda mungkin menginginkan sesuatu seperti ini:
Map<String, String> map = new HashMap<String, String>(); for (String key : properties.stringPropertyNames()) { map.put(key, properties.getProperty(key)); }
sumber
Properties<String,String> properties = new Properties<String,String>();
. Aneh.Properties
itu sendiri tidak generik.Saya akan menggunakan Guava API berikut: com.google.common.collect.Maps # fromProperties
Properties properties = new Properties(); Map<String, String> map = Maps.fromProperties(properties);
sumber
Jika Anda tahu bahwa
Properties
objek Anda hanya berisi<String, String>
entri, Anda dapat menggunakan tipe mentah:Properties properties = new Properties(); Map<String, String> map = new HashMap<String, String>((Map) properties);
sumber
Masalahnya adalah yang
Properties
mengimplementasikanMap<Object, Object>
, sedangkanHashMap
konstruktor mengharapkan aMap<? extends String, ? extends String>
.Jawaban ini menjelaskan keputusan (yang cukup berlawanan dengan intuisi) ini. Singkatnya: sebelum Java 5,
Properties
diimplementasikanMap
(karena tidak ada obat generik saat itu). Ini berarti Anda bisa meletakkan apa sajaObject
di dalam sebuahProperties
benda. Ini masih dalam dokumentasi:Untuk menjaga kompatibilitas dengan ini, para desainer tidak punya pilihan lain selain membuatnya mewarisi
Map<Object, Object>
di Java 5. Ini adalah hasil yang disayangkan dari upaya untuk kompatibilitas mundur penuh yang membuat kode baru tidak perlu berbelit-belit.Jika Anda hanya pernah menggunakan properti string di
Properties
objek Anda, Anda harus bisa lolos dengan cast yang tidak dicentang di konstruktor Anda:Map<String, String> map = new HashMap<String, String>( (Map<String, String>) properties);
atau tanpa salinan apa pun:
sumber
public HashMap(Map<? extends K, ? extends V> m)
. Itu tidak mengharapkanMap<String, String>
Map<Object, Object>
tidak dapat digunakan untuk argumen formal tipe` Map <? memperluas String,? memperluas String> `.ini hanya karena konstruktor HashMap memerlukan argumen tipe generik Map dan Properties mengimplementasikan Map.
Ini akan berhasil, meskipun dengan peringatan
Properties properties = new Properties(); Map<String, String> map = new HashMap(properties);
sumber
Anda dapat menggunakan ini:
Map<String, String> map = new HashMap<>(); props.forEach((key, value) -> map.put(key.toString(), value.toString()));
sumber
Hal pertama,
Tidak ada konstruktor dalam kelas HashMap yang mengambil objek properti dan mengembalikan Anda objek hashmap. Jadi apa yang Anda lakukan TIDAK benar. Anda harus dapat mentransmisikan objek properti ke referensi yang memiliki hashtable.
sumber
saya menggunakan ini:
for (Map.Entry<Object, Object> entry:properties.entrySet()) { map.put((String) entry.getKey(), (String) entry.getValue()); }
sumber