How can I write Java properties in a defined order?

女生的网名这么多〃 提交于 2019-12-17 18:16:34

问题


I'm using java.util.Properties's store(Writer, String) method to store the properties. In the resulting text file, the properties are stored in a haphazard order.

This is what I'm doing:

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

How can I ensure the properties are written out in alphabetical order, or in the order the properties were added?

I'm hoping for a solution simpler than "manually create the properties file".


回答1:


As per "The New Idiot's" suggestion, this stores in alphabetical key order.

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



回答2:


See https://github.com/etiennestuder/java-ordered-properties for a complete implementation that allows to read/write properties files in a well-defined order.

OrderedProperties properties = new OrderedProperties();
properties.load(new FileInputStream(new File("~/some.properties")));



回答3:


To use a TreeSet is dangerous! Because in the CASE_INSENSITIVE_ORDER the strings "mykey", "MyKey" and "MYKEY" will result in the same index! (so 2 keys will be omitted).

I use List instead, to be sure to keep all keys.

 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:


The solution from Steve McLeod did not not work when trying to sort case insensitive.

This is what I came up with

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



回答5:


Steve McLeod's answer used to work for me, but since Java 11, it doesn't.

The problem seemed to be EntrySet ordering, so, here you go:

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

I will warn that this is not fast by any means. It forces iteration over a LinkedHashSet which isn't ideal, but I'm open to suggestions.



来源:https://stackoverflow.com/questions/17011108/how-can-i-write-java-properties-in-a-defined-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!