Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?
java.util.Properties
es una implementación del constructor de java.util.Map
, And recibe un tipo param. Entonces, ¿por qué debe convertirse explícitamente?java.util.HashMap
Map
Hashtable<Object, Object>
, incluso cosas que no son cadenas, incluso teclas que no son cadenas.La forma eficiente de hacerlo es simplemente convertir a un mapa genérico de la siguiente manera:
Properties props = new Properties(); Map<String, String> map = (Map)props;
Esto convertirá un
Map<Object, Object>
mapa en un mapa sin formato, que está "bien" para el compilador (solo advertencia). Una vez que tengamos un rawMap
se lanzará alMap<String, String>
que también estará "ok" (otra advertencia). Puedes ignorarlos con una anotación.@SuppressWarnings({ "unchecked", "rawtypes" })
Esto funcionará porque en la JVM el objeto realmente no tiene un tipo genérico. Los tipos genéricos son solo un truco que verifica las cosas en tiempo de compilación.
Si alguna clave o valor no es una cadena, producirá un
ClassCastException
error. Con laProperties
implementación actual , es muy poco probable que esto suceda, siempre y cuando no use los métodos de llamada mutables del superHashtable<Object,Object>
deProperties
.Entonces, si no hace cosas desagradables con su instancia de Propiedades, este es el camino a seguir.
fuente
Map
instancia al menos en el código dado, así que pensé que esto es lo que necesitaPodrías usar Google Guava's:
com.google.common.collect.Maps.fromProperties (Propiedades)
fuente
¿Qué tal esto?
Map properties = new Properties(); Map<String, String> map = new HashMap<String, String>(properties);
Causará una advertencia, pero funciona sin iteraciones.
fuente
Map<Object, Object>
, es unMap
argumento (tipo sin formato ). Esta respuesta es correcta(Map<String, String>) ((Map) properties)
La forma Java 8:
fuente
Properties
implementosMap<Object, Object>
- noMap<String, String>
.Estás intentando llamar a este constructor:
public HashMap(Map<? extends K,? extends V> m)
... con
K
yV
ambos comoString
.Pero
Map<Object, Object>
no es unMap<? extends String, ? extends String>
... puede contener claves y valores que no sean cadenas.Esto funcionaría:
Map<Object, Object> map = new HashMap<Object, Object>();
... pero no te sería tan útil.
Fundamentalmente,
Properties
nunca debería haber sido una subclase deHashTable
... ese es el problema. Desde v1, siempre ha sido posible almacenar claves y valores que no son de cadena, a pesar de que eso va en contra de la intención. Si se hubiera utilizado la composición en su lugar, la API solo podría haber funcionado con claves / valores de cadena, y todo habría ido bien.Es posible que desee algo como esto:
Map<String, String> map = new HashMap<String, String>(); for (String key : properties.stringPropertyNames()) { map.put(key, properties.getProperty(key)); }
fuente
Properties<String,String> properties = new Properties<String,String>();
. Peculiar.Properties
sí mismo no es genérico.Usaría la siguiente API de Guava: com.google.common.collect.Maps # fromProperties
Properties properties = new Properties(); Map<String, String> map = Maps.fromProperties(properties);
fuente
Si sabe que su
Properties
objeto solo contiene<String, String>
entradas, puede recurrir a un tipo sin formato:Properties properties = new Properties(); Map<String, String> map = new HashMap<String, String>((Map) properties);
fuente
El problema es que
Properties
implementaMap<Object, Object>
, mientras que elHashMap
constructor espera unMap<? extends String, ? extends String>
.Esta respuesta explica esta decisión (bastante contraria a la intuición). En resumen: antes de Java 5,
Properties
implementadoMap
(ya que no había genéricos en ese entonces). Esto significaba que podía poner cualquieraObject
en unProperties
objeto. Esto todavía está en la documentación:Para mantener la compatibilidad con esto, los diseñadores no tuvieron otra opción que heredarlo
Map<Object, Object>
en Java 5. Es un resultado desafortunado del esfuerzo por lograr una compatibilidad total con versiones anteriores que hace que el nuevo código sea innecesariamente complicado.Si solo usa propiedades de cadena en su
Properties
objeto, debería poder salirse con una conversión sin marcar en su constructor:Map<String, String> map = new HashMap<String, String>( (Map<String, String>) properties);
o sin copias:
fuente
public HashMap(Map<? extends K, ? extends V> m)
. No espera unMap<String, String>
Map<Object, Object>
no se puede usar para un argumento formal de tipo` Map <? extiende String,? extiende Cadena> `.esto es solo porque el constructor de HashMap requiere un argumento de tipo Map genérico y Propiedades implementa Map.
Esto funcionará, aunque con una advertencia
Properties properties = new Properties(); Map<String, String> map = new HashMap(properties);
fuente
Puedes usar esto:
Map<String, String> map = new HashMap<>(); props.forEach((key, value) -> map.put(key.toString(), value.toString()));
fuente
Lo primero,
No existe tal constructor en la clase HashMap que toma un objeto de propiedades y le devuelve un objeto hashmap. Entonces, lo que estás haciendo NO es correcto. Debería poder convertir el objeto de propiedades en una referencia de tabla hash.
fuente
yo uso esto:
for (Map.Entry<Object, Object> entry:properties.entrySet()) { map.put((String) entry.getKey(), (String) entry.getValue()); }
fuente