1. 简介
在本篇教程中,我们将聚焦于如何将两个或多个 Java 的 Properties
对象合并为一个。
我们会介绍三种不同的实现方式:
✅ 首先是使用迭代的方式;
✅ 接着是使用 putAll()
方法;
✅ 最后,使用 Java 8 的 Stream API 来实现更现代化的写法。
如果你还不太熟悉 Java Properties 的基本使用,可以先看看我们这篇 入门文章。
2. Properties 使用回顾
在开始合并操作之前,我们快速回顾一下 Properties 的核心概念。
Properties 通常用于定义应用的配置项,它以键值对的形式存储数据,且键和值都必须是字符串类型。
在 Java 中,我们通过 java.util.Properties
类来管理这些键值对。⚠️ 需要注意的是,Properties
类继承自 Hashtable
。
如果你对 Hashtable
还不熟悉,可以阅读我们的 这篇文章。
2.1. 创建 Properties 示例
为了方便演示,我们采用程序化的方式创建 Properties:
private Properties propertiesA() {
Properties properties = new Properties();
properties.setProperty("application.name", "my-app");
properties.setProperty("application.version", "1.0");
return properties;
}
上面这段代码创建了一个 Properties
对象,并通过 setProperty()
方法设置了两个配置项。
⚠️ 注意:虽然 setProperty()
内部调用了 Hashtable
的 put()
方法,但它确保了键和值都是字符串类型。
❌ 不推荐直接使用 put()
方法,因为它允许插入非字符串类型的键或值,这会破坏 Properties 的语义。
3. 方式一:使用迭代合并 Properties
我们先来看一个通过迭代合并多个 Properties 的方式:
private Properties mergePropertiesByIteratingKeySet(Properties... properties) {
Properties mergedProperties = new Properties();
for (Properties property : properties) {
Set<String> propertyNames = property.stringPropertyNames();
for (String name : propertyNames) {
String propertyValue = property.getProperty(name);
mergedProperties.setProperty(name, propertyValue);
}
}
return mergedProperties;
}
步骤解析:
- 创建一个新的
Properties
对象用于存放合并后的结果; - 遍历传入的所有
Properties
对象; - 使用
stringPropertyNames()
获取每个对象中所有键名; - 遍历这些键名,获取对应的值;
- 将键值对放入合并后的对象中。
✅ 这种方式虽然啰嗦,但逻辑清晰,适合需要精细控制的场景。
4. 方式二:使用 putAll()
方法
接下来我们使用 putAll()
方法来合并 Properties:
private Properties mergePropertiesByUsingPutAll(Properties... properties) {
Properties mergedProperties = new Properties();
for (Properties property : properties) {
mergedProperties.putAll(property);
}
return mergedProperties;
}
和前面类似,我们创建一个目标 Properties
对象,然后依次调用 putAll()
方法将每个 Properties
对象中的键值对复制进去。
⚠️ 注意:putAll()
是从 Hashtable
继承而来的方法,它会把另一个 Map 中的所有映射拷贝到当前对象中。
❌ 同样,不推荐直接使用 putAll()
来处理非字符串类型的 Map,因为这可能导致类型不一致的问题。
5. 方式三:使用 Stream API 合并
最后,我们使用 Java 8 的 Stream API 来实现更优雅的合并方式:
private Properties mergePropertiesByUsingStreamApi(Properties... properties) {
return Stream.of(properties)
.collect(Properties::new, Map::putAll, Map::putAll);
}
这里我们使用了 Stream.of()
将多个 Properties
转换为流,然后通过 collect()
方法将它们归约为一个 Properties
对象。
三个参数说明如下:
- 第一个参数是
Supplier
,用于创建新的结果容器(这里是new Properties()
); - 第二个参数是累加器(accumulator),用于将元素合并到结果容器中(这里是
Map::putAll
); - 第三个参数是组合器(combiner),用于并行流中合并多个结果容器(这里也是
Map::putAll
)。
✅ 这种方式简洁高效,适合追求代码风格的场景。
如果你对 Stream API 还不熟悉,可以看看我们这篇 入门指南。
6. 总结
本篇教程我们介绍了三种合并 Properties
对象的方式:
方式 | 特点 |
---|---|
迭代合并 | 逻辑清晰,适合自定义控制 |
putAll() 方法 |
简洁,但要注意类型安全 |
Stream API | 现代化写法,代码简洁优雅 |
所有示例代码都可以在我们的 GitHub 仓库 中找到。