Ich verwende die Methode store (Writer, String) von Java.util.Properties, um die Eigenschaften zu speichern. In der resultierenden Textdatei werden die Eigenschaften in zufälliger Reihenfolge gespeichert.
Das mache ich:
Properties properties = createProperties();
properties.store(new FileWriter(file), null);
Wie kann ich sicherstellen, dass die Eigenschaften in alphabetischer Reihenfolge geschrieben werden oder in der Reihenfolge, in der die Eigenschaften hinzugefügt wurden?
Ich hoffe auf eine Lösung, die einfacher ist als das Erstellen der Eigenschaftendatei.
Gemäß dem Vorschlag von "The New Idiot" wird dies in alphabetischer Reihenfolge gespeichert.
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);
Unter https://github.com/etiennestuder/Java-ordered-properties finden Sie eine vollständige Implementierung, die das Lesen/Schreiben von Eigenschaftendateien in einer definierten Reihenfolge ermöglicht.
OrderedProperties properties = new OrderedProperties();
properties.load(new FileInputStream(new File("~/some.properties")));
Die Verwendung einer TreeSet
ist gefährlich! Im CASE_INSENSITIVE_ORDER
führen die Zeichenfolgen "mykey", "MyKey" und "MYKEY" zum gleichen Index! (so werden 2 Schlüssel weggelassen).
Ich benutze stattdessen List
, um sicherzugehen, dass alle Schlüssel erhalten bleiben.
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 );
Die Lösung von Steve McLeod funktionierte nicht, wenn versucht wurde, die Groß- und Kleinschreibung zu unterscheiden.
Das ist was ich gefunden habe
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);
}
Steve McLeods Antwort funktionierte früher für mich, aber seit Java 11 nicht.
Das Problem schien die Bestellung von EntrySet zu sein, also los geht's:
@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)));
}
};
}
Ich werde darauf hinweisen, dass dies keinesfalls schnell ist. Es zwingt die Iteration über ein LinkedHashSet, das nicht ideal ist, aber ich bin offen für Vorschläge.