我正在使用java.util.Properties的store(Writer,String)方法来存储属性。在生成的文本文件中,属性以偶然的顺序存储。
这就是我正在做的事情:
Properties properties = createProperties();
properties.store(new FileWriter(file), null);
如何确保按字母顺序或按属性添加顺序写出属性?
我希望解决方案比“手动创建属性文件”更简单。
答案 0 :(得分:56)
按照“新白痴”的建议,按字母顺序排列。
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);
答案 1 :(得分:9)
有关允许以明确定义的顺序读/写属性文件的完整实现,请参阅https://github.com/etiennestuder/java-ordered-properties。
OrderedProperties properties = new OrderedProperties();
properties.load(new FileInputStream(new File("~/some.properties")));
答案 2 :(得分:1)
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);
}
答案 3 :(得分:1)
使用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 );
答案 4 :(得分:1)
史蒂夫·麦克劳德(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进行迭代,这并不理想,但我愿意提出建议。