How can I write Java properties in a defined order?

前端 未结 5 952
粉色の甜心
粉色の甜心 2020-12-05 06:47

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.

相关标签:
5条回答
  • 2020-12-05 07:38

    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);
    
    0 讨论(0)
  • 2020-12-05 07:41

    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")));
    
    0 讨论(0)
  • 2020-12-05 07:41

    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.

    0 讨论(0)
  • 2020-12-05 07:51

    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 );
    
    0 讨论(0)
  • 2020-12-05 07:52

    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);
        }
    
    0 讨论(0)
提交回复
热议问题