簡體   English   中英

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

[英]How do I make a copy of java.util.Properties object?

我有以下字段和構造函數:

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()很棒......如果你需要繼續使用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否則不建議使用Hashtable 來自維基

如果您不希望修改集合,或者期望集合保持不變,那么將其防御性地復制到不可變集合中是一種很好的做法。

重要說明:每個Guava不可變集合實現都拒絕空值。 我們對Google的內部代碼庫進行了詳盡的研究,結果表明,大約5%的時間內,null元素在集合中被允許,而其他95%的情況最好是在空值上快速失敗。 如果需要使用空值,請考慮在允許null的集合實現上使用Collections.unmodifiableList及其朋友。 更詳細的建議可以在這里找到。

屬性實現Cloneable,因此如果您願意,您可以執行以下操作。

this.properties = (Properties) properties.clone();

將此添加到您的班級

protected Object clone() throws CloneNotSupportedException {
    return super.clone();
}

或者如果你擔心使用clone,你的類也實現了serializable,所以你可以這樣做。

import org.apache.commons.lang.SerializationUtils;

this.properties = SerializationUtils.clone(properties);

性的判定

可復制

試試這個:

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

或者你可以用“長”方式做到:

    Iterator i = properties.keySet().iterator();
    while(i.hasNext()){
        this.properties.put(i.next(), properties.get(i));
    }

Iterator來自與屬性相同的java.util包,因此沒有外部依賴項。

如果關於未經檢查的類型的編譯器警告困擾您,您可以簡單地將其更改為(假設您的屬性鍵是字符串):

    Iterator<Object> i = properties.keySet().iterator();
    while(i.hasNext()){
        this.properties.put(i.next().toString(), properties.get(i));
    }

下面的程序將一個屬性文件復制到另一個屬性文件,也將刪除重復項。 源屬性文件可能具有重復的屬性,但它將創建沒有任何重復屬性的新文件。

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();
        }
    }

}

另一種方法是簡單地

Properties newVersion = new Properties(originalVersion);

它將最初表現originalVersion的副本,除非當newVersion的鍵被刪除時,它將恢復為originalVersion存儲的值。 實際上, originalVersion表現為默認的鍵/值集。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM