如何制作java.util.Properties对象的副本?

Mic*_*das 16 java collections copy properties copy-constructor

我有以下字段和构造函数:

private final Properties properties;

public PropertiesExpander(Properties properties) {
    this.properties = properties;
}
Run Code Online (Sandbox Code Playgroud)

好的做法是在构造函数中复制每个可变集合.我想制作一份浅薄的独立副本.我怎样才能做到这一点?

我的第一个想法是使用putAll()方法:

private final Properties properties = new Properties();

public PropertiesExpander(Properties properties) {
    this.properties.putAll(properties);
}
Run Code Online (Sandbox Code Playgroud)

有没有更简单,更高效或更惯用的方式呢?也许在Guava或Apache Commons中有一些实用工具?

dur*_*597 14

使用putAll()很棒......如果你需要留下来Properties.它运行O(number of elements)并且开销很小.我建议的唯一区别是远离Properties性能原因,除非你需要它,因为它继承自Hashtable.另外,不要使用,Properties因为它实际上并不符合任何接口,只是Dictionary一个抽象类; 这将限制您的选择.请参阅:"编程到接口"是什么意思?

从Java 2平台v1.2开始,这个类被改进以实现Map接口,使其成为Java Collections Framework的成员.与新的集合实现不同,Hashtable是同步的.如果不需要线程安全的实现,建议使用它来HashMap代替Hashtable.如果需要线程安全的高度并发实现,则建议使用ConcurrentHashMap代替Hashtable.

无论你做什么,不要使用clone(),它不安全,不具备性能.请参阅:Java:为什么不将clone()用于防御性复制?


你编辑了你的问题,询问番石榴和apache-commons.如果它纯粹是一个防御性的副本,并且它是不可改变的,我建议使用Map<String, String> map = ImmutableMap.copyOf(properties).注意:同样,这不使用实际Properties对象,因为Hashtable除非您需要,否则不建议使用它.来自维基

如果您不希望修改集合,或者期望集合保持不变,那么将其防御性地复制到不可变集合中是一种很好的做法.

重要说明:每个Guava不可变集合实现都拒绝空值.我们对Google的内部代码库进行了详尽的研究,结果表明,大约5%的时间内,集合中允许使用null元素,而其他95%的情况最好是通过在null上快速失败来实现的.如果需要使用空值,请考虑在允许null的集合实现上使用Collections.unmodifiableList及其朋友.更详细的建议可以在这里找到.