Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?
java.util.Propertieses una implementación del constructor de java.util.Map, And recibe un tipo param. Entonces, ¿por qué debe convertirse explícitamente?java.util.HashMapMap

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 rawMapse 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
ClassCastExceptionerror. Con laPropertiesimplementació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
Mapinstancia 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 unMapargumento (tipo sin formato ). Esta respuesta es correcta(Map<String, String>) ((Map) properties)La forma Java 8:
fuente
PropertiesimplementosMap<Object, Object>- noMap<String, String>.Estás intentando llamar a este constructor:
public HashMap(Map<? extends K,? extends V> m)... con
KyVambos 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,
Propertiesnunca 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.Propertiessí 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
Propertiesobjeto 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
PropertiesimplementaMap<Object, Object>, mientras que elHashMapconstructor espera unMap<? extends String, ? extends String>.Esta respuesta explica esta decisión (bastante contraria a la intuición). En resumen: antes de Java 5,
PropertiesimplementadoMap(ya que no había genéricos en ese entonces). Esto significaba que podía poner cualquieraObjecten unPropertiesobjeto. 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
Propertiesobjeto, 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