Java Properties
遍历方法详解
在 Java 中遍历 Properties
对象有多种方式,以下是完整的遍历方法及其适用场景:
1. 标准遍历方法
(1)通过 keySet()
遍历
java
java
Properties props = new Properties();
props.load(new FileInputStream("config.properties"));
// 遍历所有键
for (String key : props.stringPropertyNames()) {
String value = props.getProperty(key);
System.out.println(key + " = " + value);
}
- 特点 :直接获取所有键名(
String
类型),避免类型转换。
(2)通过 entrySet()
遍历(需类型转换)
java
java
for (Map.Entry<Object, Object> entry : props.entrySet()) {
String key = (String) entry.getKey();
String value = (String) entry.getValue();
System.out.println(key + " = " + value);
}
- 注意 :需要手动将
Object
转为String
(因为Properties
继承自Hashtable<Object,Object>
)。
2. Java 8+ 简化遍历
(1)使用 forEach()
方法
java
java
props.forEach((key, value) ->
System.out.println(key + " = " + value)
);
-
优势:代码简洁,但仍需类型转换:
java
java
props.forEach((k, v) -> {
String key = (String) k;
String value = (String) v;
System.out.println(key + " : " + value);
});
(2)通过 stringPropertyNames()
+ Lambda
java
java
props.stringPropertyNames()
.forEach(key -> System.out.println(key + " -> " + props.getProperty(key)));
- 推荐:无需类型转换,直接操作字符串键值。
3. 枚举遍历(旧版兼容)
java
java
Enumeration<?> names = props.propertyNames();
while (names.hasMoreElements()) {
String key = (String) names.nextElement();
String value = props.getProperty(key);
System.out.println(key + " = " + value);
}
- 适用场景:兼容 JDK 1.0 的老代码,现代开发中不推荐。
4. 遍历时注意事项
-
键值类型:
-
Properties
的键值实际存储为Object
,但设计上应为String
。 -
使用
stringPropertyNames()
可避免类型转换。
-
-
默认值处理:
java
// 获取带默认值的属性 String value = props.getProperty("non_existent_key", "default_value");
-
线程安全:
Properties
继承自Hashtable
,是线程安全的,但遍历时若并发修改可能抛ConcurrentModificationException
。
5. 完整示例
java
java
import java.io.*;
import java.util.Properties;
public class PropertiesTraversal {
public static void main(String[] args) throws IOException {
Properties props = new Properties();
props.load(new FileInputStream("config.properties"));
// 方法1:stringPropertyNames()
System.out.println("--- 方法1 ---");
for (String key : props.stringPropertyNames()) {
System.out.println(key + " = " + props.getProperty(key));
}
// 方法2:Java 8 forEach
System.out.println("--- 方法2 ---");
props.forEach((k, v) -> System.out.println(k + " : " + v));
// 方法3:entrySet()
System.out.println("--- 方法3 ---");
props.entrySet().forEach(entry ->
System.out.println(entry.getKey() + " -> " + entry.getValue())
);
}
}
6. 性能对比
方法 | 可读性 | 类型安全 | 适用场景 |
---|---|---|---|
stringPropertyNames() |
★★★★★ | ★★★★★ | 推荐(无类型转换) |
forEach() |
★★★★☆ | ★★★☆☆ | Java 8+ 简洁写法 |
entrySet() |
★★★☆☆ | ★★☆☆☆ | 需手动类型转换 |
propertyNames() |
★★☆☆☆ | ★★☆☆☆ | 老旧代码兼容 |
7. 记忆技巧
"遍历
Properties
三件宝:
stringPropertyNames()
最稳妥,
forEach()
写起来少,老旧系统才用枚举搞。"
8. 面试常见问题
-
Properties
的键值是什么类型?- 存储时为
Object
,但约定应为String
。
- 存储时为
-
如何安全遍历
Properties
?- 优先用
stringPropertyNames()
,避免类型转换问题。
- 优先用
-
Properties
和Map
的遍历有何区别?Properties
提供专用的stringPropertyNames()
,而Map
需用keySet()
或entrySet()
。
9. 实战建议
-
推荐 :始终使用
stringPropertyNames()
遍历,避免类型转换陷阱。 -
复杂场景:若需过滤或处理键值,可用 Stream API:
java
props.stringPropertyNames().stream() .filter(key -> key.startsWith("db.")) .forEach(key -> System.out.println(key));
如果需要处理更复杂的配置(如嵌套结构),建议转为 YAML/JSON 并使用相应库(如 SnakeYAML 或 Gson)。