web-dev-qa-db-fra.com

Comment fusionner deux objets Java.util.Properties?

J'essaie d'avoir une valeur par défaut Java.util.Properties objet dans ma classe, avec les propriétés par défaut qu'il accepte, et laissez le développeur remplacer certaines d'entre elles en spécifiant une autre Java.util.Properties objet, mais je n'ai pas pu trouver une belle façon de le faire.

L'utilisation prévue est la suivante:

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);
//
59
Igor

Java.util.Properties Implémente l'interface Java.util.Map, Donc vous pouvez le traitez comme tel et utilisez des méthodes comme putAll pour ajouter le contenu d'un autre Map.

Cependant, si vous le traitez comme une carte, vous devez être très prudent avec ceci:

new Properties(defaultProperties);

Cela surprend souvent les gens, car il ressemble comme un constructeur de copie, mais ce n'est pas le cas. Si vous utilisez ce constructeur, puis appelez quelque chose comme keySet() (hérité de sa superclasse Hashtable), vous obtiendrez un ensemble vide, car les méthodes Map de Properties ne tient pas compte de l'objet Properties par défaut que vous avez transmis au constructeur. Les valeurs par défaut ne sont reconnues que si vous utilisez les méthodes définies dans Properties lui-même, telles que getProperty et propertyNames, entre autres.

Donc, si vous devez fusionner deux objets Propriétés, il est plus sûr de le faire:

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

Cela vous donnera des résultats plus prévisibles, plutôt que de désigner arbitrairement l'un d'eux comme l'ensemble de propriétés "par défaut".

Normalement, je recommanderais de ne pas traiter Properties comme Map, car c'était (à mon avis) une erreur d'implémentation dès les premiers jours de Java (Propriétés aurait dû contenir un Hashtable, pas l'étendre - c'était une conception paresseuse), mais l'interface anémique définie dans Properties lui-même ne nous donne pas beaucoup d'options.

125
skaffman

En supposant que vous souhaitiez éventuellement lire les propriétés d'un fichier, je choisirais de charger les deux fichiers dans le même objet de propriétés, comme:

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

Tu es presque bon:

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

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

EDIT: remplacé put par setProperty.

4
Jerome

Oui, vous avez raison, appelez simplement la méthode putAll et vous avez terminé.

1
OscarRyz

putAll (): copie tous les mappages de la carte spécifiée vers cette table de hachage. Ces mappages remplaceront tous les mappages que cette table de hachage possédait pour l'une des clés actuellement dans la carte spécifiée.

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

La ligne 2 n'a aucun effet. Aucune des propriétés du premier fichier ne se trouvera dans l'objet de propriétés fusionné.

1
Volker B.