简体   繁体   English

如何合并两个java.util.Properties对象?

[英]How to merge two java.util.Properties objects?

I'm trying to have a default java.util.Properties object in my class, with the default properties it accepts, and let the developer override some of them by specifying another java.util.Properties object, but I couldn't find a nice way for doing that. 我正在尝试在我的类中使用默认的java.util.Properties对象,使用它接受的默认属性,并让开发人员通过指定另一个java.util.Properties对象来覆盖其中一些对象,但我找不到这样做的好方法。

The intended usage is the following: 预期用途如下:

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

java.util.Properties implements the java.util.Map interface, and so you can just treat it as such, and use methods like putAll to add the contents of another Map . java.util.Properties实现java.util.Map接口,因此你可以这样处理它,并使用像putAll这样的方法来添加另一个Map的内容。

However, if you treat it like a Map, you need to be very careful with this: 但是,如果您将其视为地图,则需要非常小心:

new Properties(defaultProperties);

This often catches people out, because it looks like a copy constructor, but it isn't. 这通常会让人们失望,因为它看起来像一个复制构造函数,但事实并非如此。 If you use that constructor, and then call something like keySet() (inherited from its Hashtable superclass), you'll get an empty set, because the Map methods of Properties do not take account of the default Properties object that you passed into the constructor. 如果你使用那个构造函数,然后调用类似keySet() (继承自它的Hashtable超类)的东西,你将得到一个空集,因为PropertiesMap方法没有考虑你传递给它的默认Properties对象。构造函数。 The defaults are only recognised if you use the methods defined in Properties itself, such as getProperty and propertyNames , among others. 只有在使用Properties本身定义的方法时才会识别默认值,例如getPropertypropertyNames等。

So if you need to merge two Properties objects, it is safer to do this: 因此,如果您需要合并两个Properties对象,则执行此操作会更安全:

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

This will give you more predictable results, rather than arbitrarily labelling one of them as the "default" property set. 这将为您提供更可预测的结果,而不是任意将其中一个标记为“默认”属性集。

Normally, I would recommend not treating Properties as a Map , because that was (in my opinion) an implementation mistake from the early days of Java (Properties should have contained a Hashtable , not extended it - that was lazy design), but the anemic interface defined in Properties itself doesn't give us many options. 通常情况下,我建议不要将Properties视为Map ,因为那是(在我看来)Java早期的一个实现错误(属性应该包含一个Hashtable ,而不是扩展它 - 这是懒惰的设计),但是贫血在Properties定义的接口并没有给我们很多选择。

Assuming you eventually would like to read the properties from a file, I'd go for loading both files in the same properties object like: 假设您最终想从文件中读取属性,我会在同一个属性对象中加载两个文件,如:

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

You're almost good: 你几乎是好的:

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

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

EDIT: replaced put by setProperty . 编辑:setProperty替换put

是的,你只是调用putAll方法,你就完成了。

putAll(): Copies all of the mappings from the specified map to this hashtable. putAll():将指定映射中的所有映射复制到此哈希表。 These mappings will replace any mappings that this hashtable had for any of the keys currently in the specified map. 这些映射将替换此哈希表对当前在指定映射中的任何键所具有的任何映射。

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

Line 2 has no effect at all. 第2行完全没有效果。 None of the properties from the first file will be in the merged properties object. 第一个文件中的所有属性都不在合并的属性对象中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM