2010-01-05 17 views
50

Estoy tratando de tener un objeto predeterminado java.util.Properties en mi clase, con las propiedades predeterminadas que acepta, y dejar que el desarrollador anule algunos de ellos especificando otro objeto java.util.Properties, pero no pude encontrar una buena manera de hacerlo.Cómo fusionar dos objetos java.util.Properties?

El uso previsto es el siguiente:

Properties defaultProperties = new Properties(); 
defaultProperties.put("key1", "value1"); 
defaultProperties.put("key2", "value2"); 

Properties otherProperties = new Properties(); 
otherProperties.put("key2", "value3"); 

Properties finalProperties = new Properties(defaultProperties); 

// 
// I'd expect to have something like: 
// 
// finalProperties.merge(otherProperties); 
// 
+0

Alguien respondió pero eliminó la respuesta, indicando que la forma correcta sería usar el método 'putAll()', que es la respuesta correcta y logró lo que quería. No me he dado cuenta de que 'java.util.Properties' extiende' java.util.Hashtable'. – Igor

+0

¿Por qué crees que mi respuesta es incorrecta? – Jerome

+1

No es técnicamente incorrecto, pero lo que quería era fusionar dos archivos 'java.util.Properties' sin iterar sus contenidos, y es exactamente lo que hace el método' putAll() '. – Igor

Respuesta

111

java.util.Properties implementa la interfaz java.util.Map, y por lo que puede simplemente tratarlo como tal, y utilizar métodos como putAll para agregar el contenido de otro Map.

Sin embargo, si lo trata como un mapa, es necesario tener mucho cuidado con esto:

new Properties(defaultProperties); 

Esto a menudo atrapa a la gente, porque ve como un constructor de copia, pero ISN' t. Si usa ese constructor y luego llama a algo como keySet() (heredado de su superclase Hashtable), obtendrá un conjunto vacío, porque los métodos Map de Properties no tienen en cuenta el objeto predeterminado Properties que pasó al constructor. Los valores predeterminados solo se reconocen si utiliza los métodos definidos en Properties, como getProperty y propertyNames, entre otros.

Así que si usted necesita combinar dos propiedades de los objetos, es más seguro para hacer esto:

Properties merged = new Properties(); 
merged.putAll(properties1); 
merged.putAll(properties2); 

Esto le dará resultados más predecibles, en lugar de etiquetar arbitrariamente uno de ellos como el conjunto de propiedades "por defecto" .

Normalmente, yo recomendaría no tratar Properties como Map, porque esa era (en mi opinión) un error de aplicación a partir de los primeros días de Java (Propiedades deberían haber contenido una Hashtable, no se extendió - que era el diseño perezoso) , pero la interfaz anémica definida en Properties en sí misma no nos da muchas opciones.

+2

Genial, estaba a punto de escribir exactamente lo que ha descrito. Me salvas un error. – Igor

+2

Otro peligro de ver propiedades como un mapa es que no está "genérico": 'propiedades.put (" clave ", nuevo objeto())' se compilará. – Jerome

+1

Recopilará, sí, y en algunos casos funcionará bien, siempre y cuando lo saques nuevamente usando 'get()', y no intentes recuperarlo usando 'getProperty()'. – skaffman

4

Ya casi bueno:

Properties defaultProperties = new Properties(); 
defaultProperties.setProperty("key1", "value1"); 
defaultProperties.setProperty("key2", "value2"); 

Properties finalProperties = new Properties(defaultProperties); 
finalProperties.setProperty("key2", "value3"); 

EDIT: reemplazado por putsetProperty.

1

Sí, tiene razón, simplemente invoque el método putAll y listo.

+0

CW para evitar tener conflictos, aunque pensé que esta era la respuesta que estaba a punto de dar – OscarRyz

18

Suponiendo que finalmente le gustaría leer las propiedades de un archivo, me gustaría ir para cargar ambos archivos en las mismas propiedades del objeto como:

Properties properties = new Properties(); 
properties.load(getClass().getResourceAsStream("default.properties")); 
properties.load(getClass().getResourceAsStream("custom.properties")); 
1

putAll(): Copia todos los mapeos de el mapa especificado para esta tabla hash. Estas asignaciones reemplazarán las asignaciones que esta hashtable tenía para cualquiera de las claves actualmente en el mapa especificado.

Properties merged = new Properties(); 
merged.putAll(properties1); 
merged.putAll(properties2); 

La línea 2 no tiene ningún efecto. Ninguna de las propiedades del primer archivo estará en el objeto de propiedades fusionadas.

+1

** Su última línea es completamente falsa **. Todas las propiedades en propiedades1 que no están presentes en propiedades2 se establecerán en el valor en propiedades1 en fusionadas. –

Cuestiones relacionadas