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

如何制作java.util.Properties对象的副本?,java,collections,properties,copy,copy-constructor,Java,Collections,Properties,Copy,Copy Constructor,我有以下字段和构造函数: private final Properties properties; public PropertiesExpander(Properties properties) { this.properties = properties; } 好的做法是在构造函数中复制每个可变集合。我想做一份浅显的、独立的拷贝。我怎样才能做到这一点 我的第一个想法是使用putAll()方法: private final Properties properties = new P

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

private final Properties properties;

public PropertiesExpander(Properties properties) {
    this.properties = properties;
}
好的做法是在构造函数中复制每个可变集合。我想做一份浅显的、独立的拷贝。我怎样才能做到这一点

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

private final Properties properties = new Properties();

public PropertiesExpander(Properties properties) {
    this.properties.putAll(properties);
}
有没有更简单、更高效或更惯用的方法?也许在Guava或Apache Commons中有一些实用程序?

使用
putAll()
非常好。。。如果您需要继续使用
属性
。它在
O(元素数)
中运行,开销非常小。我建议的唯一区别是,出于性能原因,不要使用
属性
,除非您需要它,因为它继承自。另外,不要使用
Properties
,因为它实际上不符合任何接口,只是
Dictionary
这是一个抽象类;这将限制你的选择。见:

从Java2平台v1.2开始,该类经过了改造,实现了
Map
接口,使其成为Java集合框架的成员。与新的集合实现不同,
哈希表
是同步的。如果不需要线程安全的实现,建议使用它代替
哈希表
。如果需要线程安全的高并发实现,则建议使用它代替哈希表

无论您做什么,都不要使用
clone()
它既不安全也不性能。见:


您编辑了您的问题以询问有关番石榴和apache commons的信息。如果它纯粹是一个防御性拷贝,并且它是不可变的,我建议使用。注意:同样,这不会使用实际的
Properties
对象,因为除非您需要,否则不建议使用
Hashtable
。从

当您不希望修改集合,或期望集合保持不变时,最好将其防御性地复制到不可变集合中

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


属性实现了可克隆性,因此如果需要,您可以执行以下操作

this.properties = (Properties) properties.clone();
将此添加到您的类中

protected Object clone() throws CloneNotSupportedException {
    return super.clone();
}
或者,如果您担心使用克隆,您的类还实现了serializable,所以您可以这样做

import org.apache.commons.lang.SerializationUtils;

this.properties = SerializationUtils.clone(properties);

或者您可以通过“长”的方式完成:

迭代器与属性来自同一个java.util包,因此没有外部依赖项

如果编译器关于未检查类型的警告困扰您,您只需将其更改为(假设您的属性键是字符串):

Iterator i=properties.keySet().Iterator();
while(i.hasNext()){
this.properties.put(i.next().toString(),properties.get(i));
}
试试这个:

Properties newProps = new Properties();
properties.forEach((key, value) -> {
    newProps.setProperty((String) key, (String) value);
});

下面的程序将一个属性文件复制到另一个属性文件,并将删除重复项。源属性文件可能具有重复的属性,但它将创建没有任何重复属性的新文件

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.Set;

public class App2 {

    public static void main(String[] args) {

        try (InputStream input = new FileInputStream("config.properties")) {

            Properties prop = new Properties();

            // load a properties file
            prop.load(input);

            writeToNewProperties(prop);
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

    private static void writeToNewProperties(Properties prop) {
        Properties outPutProp = new Properties();
        // get the property value and print it out
        Set<String> stringPropertyNames = prop.stringPropertyNames();
        for (String propertyName : stringPropertyNames) {
            outPutProp.put(propertyName, prop.get(propertyName));
        }

        try (OutputStream output = new FileOutputStream("out-config.properties")) {
            // save properties to project root folder
            outPutProp.store(output, null);
            System.out.println(outPutProp);
        } catch (IOException io) {
            io.printStackTrace();
        }
    }

}
import java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.OutputStream;
导入java.util.Properties;
导入java.util.Set;
公共类App2{
公共静态void main(字符串[]args){
try(InputStream input=newfileinputstream(“config.properties”)){
Properties prop=新属性();
//加载属性文件
道具载荷(输入);
writeToNewProperties(道具);
}捕获(IOEX异常){
例如printStackTrace();
}
}
私有静态void writeToNewProperties(属性属性属性){
Properties outPutProp=新属性();
//获取属性值并将其打印出来
设置stringPropertyNames=prop.stringPropertyNames();
for(字符串属性名称:stringPropertyNames){
outPutProp.put(propertyName,prop.get(propertyName));
}
try(OutputStream output=newfileoutputstream(“out config.properties”)){
//将属性保存到项目根文件夹
outPutProp.store(输出,null);
System.out.println(outPutProp);
}捕获(io异常){
io.printStackTrace();
}
}
}

this.properties=ImmutableMap.copyOf(属性)-不幸的是,这不是compile@MichalKordas
this.properties=ImmutableMap.copyOf(属性)-它使用番石榴27进行编译
Properties newProps = new Properties();
properties.forEach((key, value) -> {
    newProps.setProperty((String) key, (String) value);
});
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.Set;

public class App2 {

    public static void main(String[] args) {

        try (InputStream input = new FileInputStream("config.properties")) {

            Properties prop = new Properties();

            // load a properties file
            prop.load(input);

            writeToNewProperties(prop);
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

    private static void writeToNewProperties(Properties prop) {
        Properties outPutProp = new Properties();
        // get the property value and print it out
        Set<String> stringPropertyNames = prop.stringPropertyNames();
        for (String propertyName : stringPropertyNames) {
            outPutProp.put(propertyName, prop.get(propertyName));
        }

        try (OutputStream output = new FileOutputStream("out-config.properties")) {
            // save properties to project root folder
            outPutProp.store(output, null);
            System.out.println(outPutProp);
        } catch (IOException io) {
            io.printStackTrace();
        }
    }

}