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

如何合并两个java.util.Properties对象?,java,properties,Java,Properties,我试图在我的类中有一个默认的java.util.Properties对象,以及它接受的默认属性,并让开发人员通过指定另一个java.util.Properties对象来覆盖其中的一些属性,但我找不到一个好的方法来实现这一点 预期用途如下: Properties defaultProperties = new Properties(); defaultProperties.put("key1", "value1"); defaultProperties.put("key2", "value2");

我试图在我的类中有一个默认的
java.util.Properties
对象,以及它接受的默认属性,并让开发人员通过指定另一个
java.util.Properties
对象来覆盖其中的一些属性,但我找不到一个好的方法来实现这一点

预期用途如下:

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);
//
你几乎很好:

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

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

EDIT:
put
替换为
setProperty

是的,您是对的,只需调用putAll方法即可

java.util.Properties
实现
java.util.Map
接口,因此您可以将其视为一个接口,并使用
putAll
等方法添加另一个
Map
的内容

但是,如果将其视为地图,则需要非常小心:

new Properties(defaultProperties);
这通常会让人注意到,因为它看起来像一个复制构造函数,但事实并非如此。如果使用该构造函数,然后调用类似于
keySet()
(从其
哈希表
超类继承而来)的东西,将得到一个空集,因为
属性
映射
方法不考虑传递到构造函数中的默认
属性
对象。只有使用
Properties
本身中定义的方法,例如
getProperty
propertyNames
,才能识别默认值

因此,如果需要合并两个Properties对象,则更安全的做法是:

Properties merged = new Properties();
merged.putAll(properties1);
merged.putAll(properties2);
这将为您提供更可预测的结果,而不是任意将其中一个标记为“默认”属性集


通常,我建议不要将
属性
视为
映射
,因为(在我看来)这是Java早期的一个实现错误(属性应该包含
哈希表
,而不是扩展它-这是一个懒惰的设计),但是
Properties
中定义的贫血接口本身并没有给我们很多选择。

假设您最终想要从文件中读取属性,我会将两个文件加载到同一个Properties对象中,如:

Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("default.properties"));
properties.load(getClass().getResourceAsStream("custom.properties"));
putAll(): 将指定映射中的所有映射复制到此哈希表。这些映射将替换此哈希表对当前指定映射中的任何键所具有的任何映射

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

第2行完全没有效果。第一个文件中的属性都不在合并属性对象中。

有人回答了问题,但删除了答案,并指出正确的方法是使用
putAll()
方法,这是正确的答案,实现了我想要的。我没有注意到
java.util.Properties
扩展了
java.util.Hashtable
。为什么你认为我的答案不正确?从技术上讲,这并不是错误的,但我想要的是合并两个
java.util.Properties
文件而不迭代其内容,而这正是
putAll()所做的
method does.CW为避免冲突,即使这是我即将给出的答案,将属性视为映射的另一个危险是它不是“泛化的”:
Properties.put(“key”,new Object())
将编译。它将编译,是的,在某些情况下,它将工作正常,只要您使用
get()再次将其取出
,不要尝试使用
getProperty()
检索它。这里还有一个有价值的信息:对于属性,请始终使用
setProperty()
getProperty()
。这是对的吗?为了安全,是的,但是如果你确信你知道你在放什么,你可以通过
get()
put()
逃脱。这对我帮助很大!请注意,属性的实现类似于责任链,但是没有覆盖
#get()
#put()
,因此要使用责任链功能(从上层处理程序读取值),必须使用
#getProperty()
。依我看,继承HashMap而不重写get()/
set()
(和其他)可能不是最好的设计决策。您的最后一行完全不正确。properties1中不在properties2中的所有属性将被设置为合并中properties1中的值。