2010-01-05 11 views
50

Ich versuche, ein Standard java.util.Properties Objekt in meiner Klasse mit den Standardeigenschaften, die es akzeptiert, und lassen Sie den Entwickler überschreiben einige von ihnen, indem Sie ein anderes java.util.Properties Objekt, aber ich konnte keinen schönen Weg dafür finden.Wie zwei java.util.Properties-Objekte zusammengeführt werden?

Die beabsichtigte Verwendung ist die folgende:

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

Jemand antwortete, aber entfernte die Antwort und erklärte, dass der richtige Weg wäre, die 'putAll()' Methode zu verwenden, die die richtige Antwort ist und erreicht, was ich wollte. Ich habe nicht bemerkt, dass 'java.util.Properties'' java.util.Hashtable' erweitert. – Igor

+0

Warum denkst du, dass meine Antwort nicht korrekt ist? – Jerome

+1

Es ist technisch nicht falsch, aber was ich wollte, war zwei 'java.util.Properties' Datei zusammenführen, ohne seinen Inhalt zu iterieren, und es ist genau das, was die' putAll() 'Methode tut. – Igor

Antwort

111

java.util.Properties implementiert die java.util.Map Schnittstelle, und Sie so können nur sie als solche behandeln, und die Verwendung Methoden wie putAll den Inhalt eines anderen Map hinzuzufügen.

jedoch, wenn Sie es wie eine Karte zu behandeln, müssen Sie mit diesem sehr vorsichtig sein:

new Properties(defaultProperties); 

Dies fängt oft Menschen aus, weil es wie ein Copykonstruktor aussieht, aber es isn‘ t. Wenn Sie diesen Konstruktor verwenden und dann etwas wie keySet() (geerbt von seiner Superklasse Hashtable) aufrufen, erhalten Sie eine leere Menge, da die Map Methoden von Properties das Standardobjekt Properties nicht berücksichtigen, das Sie an den Konstruktor übergeben haben. Die Standardwerte werden nur dann erkannt, wenn Sie unter anderem die in Properties definierten Methoden wie getProperty und propertyNames verwenden.

Wenn Sie also zwei Eigenschaften fusionieren müssen Objekte, ist es sicherer, dies zu tun:

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

Dies wird Ihnen besser vorhersehbare Ergebnisse liefern, anstatt willkürlich einer von ihnen die Kennzeichnung als „default“ Eigenschaftssatz .

Normalerweise würde ich es nicht empfehlen Properties als Map Behandlung, denn das ist (meiner Meinung nach) war eine Implementierung Fehler aus den frühen Tagen von Java (Eigenschaften ein Hashtable enthalten haben sollten, nicht verlängert - das war faul Design) , aber die anämische Schnittstelle, die in Properties selbst definiert ist, gibt uns nicht viele Optionen.

+2

Großartig, ich wollte gerade genau das schreiben, was du beschrieben hast. Du rettest mir einen Fehler. – Igor

+2

Eine weitere Gefahr, Eigenschaften als Map zu sehen, ist, dass es nicht "Genericified" ist: 'properties.put (" key ", new Object())' wird kompiliert. – Jerome

+1

Es wird kompiliert, ja, und in einigen Fällen wird es gut funktionieren, solange Sie es wieder mit 'get()' herausholen, und versuchen Sie nicht, es mit 'getProperty()' abzurufen. – skaffman

4

Sie sind fast gut:

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

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

EDIT: ersetzt put durch setProperty.

1

Ja, Sie haben Recht, rufen Sie einfach die PutAll-Methode und Sie sind fertig.

+0

CW, um Konflikte zu vermeiden, dachte sogar, dass dies die Antwort war, die ich geben wollte – OscarRyz

18

Angenommen, Sie schließlich möchten die Eigenschaften aus einer Datei lesen, die ich für das Laden Sie beide Dateien in den gleichen Eigenschaften gehen würde Objekt wie:

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

putAll(): Kopiert alle der Zuordnungen aus die angegebene Karte zu dieser Hashtabelle. Diese Zuordnungen ersetzen alle Zuordnungen, die diese Hashtabelle für einen der Schlüssel in der angegebenen Zuordnung hatte.

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

Zeile 2 hat keine Wirkung. Keine der Eigenschaften aus der ersten Datei befindet sich im zusammengeführten Eigenschaftenobjekt.

+1

** Ihre letzte Zeile ist völlig falsch **. Alle Eigenschaften in properties1, die in properties2 nicht vorhanden sind, werden auf den Wert in properties1 in merged festgelegt. –

Verwandte Themen