Упорядочивание ключей в файле .properties в алфавитном порядке без учета регистра

У меня есть эта функция, которая сохраняет значения из файла .properties в карту дерева (translatedMap), затем извлекает новые значения из «keyMap» и также сохраняет их в «translatedMap». Проблема в том, что независимо от того, что я делаю, кажется, что всегда отделяются клавиши с заглавными буквами от клавиш без заглавных букв. Вот мой код:

Properties translation = new Properties(){

        private static final long serialVersionUID = 1L;

        @Override
        public synchronized Enumeration<Object> keys() {

            return Collections.enumeration(new TreeSet<Object>(super
                    .keySet()));
        }

    };


    //creates file and stores values of keyMap into the file
    try {
        TreeMap<String, String> translatedMap = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);

        InputStreamReader in = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
        translation.load(in);

        // Store all values to TreeMap and sort
        Enumeration<?> e = translation.propertyNames();
        while (e.hasMoreElements()) {
            String key = (String) e.nextElement();
            if (key.matches(".#")) {
            } else {
                String value = translation.getProperty(key);
                translatedMap.put(key, value);
            }
        }

        // Add new values to translatedMap
        for (String key : keyMap.keySet()) {
            // Handle if some keys have already been added; delete so they can be re-added
            if (translatedMap.containsKey(key)) {
                translatedMap.remove(key);
            }
            translatedMap.put(key, keyMap.get(key));
        }

        in.close();
        translation.putAll(translatedMap);
        File translationFile = new File(filePath);

        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(translationFile, false), "UTF-8");
        translation.store(out, null);

        out.close();
    } catch (IOException e) {
            e.printStackTrace();
    }
}

Вывод, который я получаю, выглядит примерно так:

CAPITALIZED_KEY1=значение1
CAPITALIZED_KEY2=значение2
верхний регистр.key=значение3
другой нижний регистр.key=значение4
morelowercase.keys=значение5

Когда я хотел бы, чтобы это вышло так:

alowercase.key=value3
anotherlowercase.key=value4
CAPITALIZED_KEY1=value1
CAPITALIZED_KEY2=value2
morelowercase.keys=value5


person Luke Gaskell    schedule 18.06.2015    source источник
comment
Я не уверен, что понимаю вашу проблему. Не могли бы вы привести краткий пример того, что происходит по сравнению с тем, что вы ожидаете?   -  person Ray    schedule 18.06.2015
comment
Пожалуйста, напишите результат, который вы получаете, и желаемый результат.   -  person user3337714    schedule 18.06.2015


Ответы (3)


Свойства не упорядочены. Неважно, в каком порядке вы вставляете в них или если вы вызываете putAll() с чем-то отсортированным, они расширяют Hashtable. См. здесь.

person user1675642    schedule 18.06.2015

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

Следовательно, переопределяйте свойства и при записи сортируйте имена без учета регистра.

public class SortedProperties extends Properties {

    @Override
    public void store(Writer writer, String comments)
            throws IOException {
        List<String> names = new ArrayList<>();
        for (Enumeration<?> en = propertyNames(); en.hasMoreElements(); ) {
            String name = en.nextElement().toString();
            names.add(name);
        }
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compareTo(String other) {
                toLowerCase().compareTo(other.toLowerCase());
            }
        });
        //... write all properties
    }
person Joop Eggen    schedule 18.06.2015
comment
Да, это немного громоздко, и мой ответ довольно примитивен. - person Joop Eggen; 19.06.2015
comment
Кажется, я не мог переопределить функцию хранилища для работы... поэтому в итоге я пошел с чем-то вроде этого... есть ли какие-то проблемы с этим? Итак, я только что понял, что не могу размещать код в комментариях, извините за все правки, - person Luke Gaskell; 19.06.2015
comment
Единственная проблема заключается в том, что ключ AAA и ключ aaa тогда равны, перезаписывая друг друга, что дает одну запись. Однако вы можете использовать простой HashMap для хранения и последующей сортировки копии keySet() - person Joop Eggen; 19.06.2015

Чтобы добиться этого, я в конечном итоге избегал функции хранилища. Я сделал сортировку внутри treeMap. Я использовал буферизованный писатель и записал в файл. нравится:

Properties translation = new Properties();


    //creates file and stores values of keyMap into the file
    try {
        TreeMap<String, String> translatedMap = new TreeMap<String, String>(new Comparator<String>() {
            public int compare(String o1, String o2) {
                return o1.toLowerCase().compareTo(o2.toLowerCase());
            }
        });

        InputStreamReader in = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
        translation.load(in);

        // Store all values to TreeMap and sort
        for (String key : translation.stringPropertyNames()) {
            keyMap.put(key, translation.getProperty(key));
        }

        in.close();


        Iterator<String> it = keyMap.keySet().iterator();
        while (it.hasNext()) {
            String key = it.next();
            translatedMap.put(key, keyMap.get(key));
        }

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath, false), "UTF-8"));

        bw.write("#" + new Date().toString());
        bw.newLine();

        Iterator<String> it2 = translatedMap.keySet().iterator();
        while (it2.hasNext()) {
            String key = it2.next();
            bw.write(key + '=' + translatedMap.get(key));
            bw.newLine();
        }


        bw.close();
    } catch (IOException e) {
            e.printStackTrace();
    }
}
person Luke Gaskell    schedule 19.06.2015