如何以定义的顺序编写Java属性?

时间:2013-06-09 15:23:09

标签: java properties-file

我正在使用java.util.Properties的store(Writer,String)方法来存储属性。在生成的文本文件中,属性以偶然的顺序存储。

这就是我正在做的事情:

Properties properties = createProperties();
properties.store(new FileWriter(file), null);

如何确保按字母顺序或按属性添加顺序写出属性?

我希望解决方案比“手动创建属性文件”更简单。

5 个答案:

答案 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进行迭代,这并不理想,但我愿意提出建议。