Подтвердить что ты не робот

Как я могу написать свойства Java в определенном порядке?

Я использую метод хранения java.util.Properties(Writer, String) для хранения свойств. В результирующем текстовом файле свойства хранятся в случайном порядке.

Это то, что я делаю:

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

Как я могу гарантировать, что свойства записываются в алфавитном порядке или в порядке добавления свойств?

Я надеюсь на решение проще, чем "вручную создать файл свойств".

4b9b3361

Ответ 1

В соответствии с предложением "Новый Идиот" это хранится в алфавитном порядке.

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

См. https://github.com/etiennestuder/java-ordered-properties для полной реализации, которая позволяет читать/записывать файлы свойств в определенном порядке.

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

Ответ 3

Решение от 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);
    }

Ответ 4

Использовать 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 );

Ответ 5

Ответ Стива Маклеода раньше работал на меня, но начиная с 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, что не идеально, но я открыт для предложений.