プロパティを格納するためにJava.util.Propertiesのstore(Writer、String)メソッドを使用しています。結果のテキストファイルでは、プロパティは不規則な順序で格納されます。
これは私がやっていることです:
Properties properties = createProperties();
properties.store(new FileWriter(file), null);
プロパティがアルファベット順に、またはプロパティが追加された順に書き込まれるようにするにはどうすればよいですか?
「プロパティファイルを手動で作成する」よりも簡単な解決策を期待しています。
「The New Idiot's」の提案に従って、これはアルファベット順で保存されます。
Properties tmp = new Properties() {
@Override
public synchronized Enumeration<Object> keys() {
return Collections.enumeration(new TreeSet<Object>(super.keySet()));
}
};
tmp.putAll(properties);
tmp.store(new FileWriter(file), null);
明確に定義された順序でプロパティファイルを読み書きできる完全な実装については、 https://github.com/etiennestuder/Java-ordered-properties を参照してください。
OrderedProperties properties = new OrderedProperties();
properties.load(new FileInputStream(new File("~/some.properties")));
TreeSet
を使用するのは危険です。 CASE_INSENSITIVE_ORDER
文字列「mykey」、「MyKey」、「MYKEY」は同じインデックスになります! (したがって、2つのキーは省略されます)。
代わりにList
を使用して、すべてのキーを確実に保持します。
List<Object> list = new ArrayList<>( super.keySet());
Comparator<Object> comparator = Comparator.comparing( Object::toString, String.CASE_INSENSITIVE_ORDER );
Collections.sort( list, comparator );
return Collections.enumeration( list );
以前はSteve McLeodの答えがうまくいきましたが、Java 11なので、うまくいきません。
問題はEntrySetの順序付けのように思われたので、次のようにします。
@SuppressWarnings("serial")
private static Properties newOrderedProperties()
{
return new Properties() {
@Override public synchronized Set<Map.Entry<Object, Object>> entrySet() {
return Collections.synchronizedSet(
super.entrySet()
.stream()
.sorted(Comparator.comparing(e -> e.getKey().toString()))
.collect(Collectors.toCollection(LinkedHashSet::new)));
}
};
}
これは決して速くないことを警告します。理想的ではないLinkedHashSetの反復を強制しますが、私は提案を受け入れます。
大文字と小文字を区別しないでソートしようとすると、Steve McLeodのソリューションが機能しませんでした。
これは私が思いついたものです
Properties newProperties = new Properties() {
private static final long serialVersionUID = 4112578634029874840L;
@Override
public synchronized Enumeration<Object> keys() {
Comparator<Object> byCaseInsensitiveString = Comparator.comparing(Object::toString,
String.CASE_INSENSITIVE_ORDER);
Supplier<TreeSet<Object>> supplier = () -> new TreeSet<>(byCaseInsensitiveString);
TreeSet<Object> sortedSet = super.keySet().stream()
.collect(Collectors.toCollection(supplier));
return Collections.enumeration(sortedSet);
}
};
// propertyMap is a simple LinkedHashMap<String,String>
newProperties.putAll(propertyMap);
File file = new File(filepath);
try (FileOutputStream fileOutputStream = new FileOutputStream(file, false)) {
newProperties.store(fileOutputStream, null);
}