Properties.propertyNames () возвращает перечисление в обратном порядке - почему? - PullRequest
4 голосов
/ 06 апреля 2011

В моем проекте я использую некоторый файл свойств. Я заметил странное поведение Properties.propertyNames (), он возвращает перечисление, что перечисление в обратном порядке. Я сделал тест: Содержимое файла:

TT.1=Development
TT.2=Application Setup / Release
TT.3=Project Management
TT.4=Meetings and Discussions

Код:

    Enumeration<?> enumeration = properties.propertyNames();
    while (enumeration.hasMoreElements()) {
        String key = (String) enumeration.nextElement();
        String value = properties.getProperty(key);
        System.out.println(key + " " + value);                        
    }

Вывод:

TT.4 Application Setup / Release
TT.3 Development
TT.2 Meetings and Discussions
TT.1 Project Management

Может кто-нибудь сказать, в чем причина? Спасибо.
Редактировать: Поскольку ключ HashTable имеет форму TT.X, где X - это число, я отсортировал его, чтобы сделать правильный порядок. Вот следующая реализация:

    this.taskTypeList = new ArrayList<String>(0); 
    Map<String, String> reverseTaskMap = new HashMap<String, String>(0);        
    Properties properties = loadTaskProperty();
    Enumeration<?> enumeration = properties.propertyNames();
    while (enumeration.hasMoreElements()) {
        String key = (String) enumeration.nextElement();
        String value = properties.getProperty(key);
        reverseTaskMap.put(key, value);            
    }

    LinkedList<Map.Entry<String, String>> linkedList = new LinkedList<Map.Entry<String, String>>(reverseTaskMap.entrySet());
    Collections.sort(linkedList, new Comparator<Map.Entry<String, String>>() {
        public int compare(Entry<String, String> object1, Entry<String, String> object2) {                            
            return Integer.valueOf(Integer.parseInt(object1.getKey().split("\\.")[1])).compareTo(Integer.valueOf(Integer.parseInt(object2.getKey().split("\\.")[1])));
        }
    });

    for (Iterator<Map.Entry<String, String>> iterator = linkedList.iterator(); iterator.hasNext(); ) {
        Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();
        taskTypeList.add(entry.getValue());
    }

Ответы [ 3 ]

9 голосов
/ 06 апреля 2011

Это совпадение.Properties не гарантирует какой-либо конкретный порядок элементов, поэтому порядок может быть произвольным.

Более конкретно, следующие детали реализации приводят к такому поведению:

  • Поскольку ваши ключи отличаются только последней буквой, их хэш-коды (производимые String.hashCode()) отличаются только последними несколькими битами.

  • Properties является подклассом Hashtable.В отличие от HashMap, HashTable не применяет дополнительную хеш-функцию для смешивания битов хеш-кода.Поскольку Hashtable использует последние биты хеш-кода в качестве номера хэш-корзины для размещения элементов, ваши элементы помещаются в последующие корзины. Это действительно интересный момент - это означает, что эта реализация Hashtable может показать худшую производительность в некоторых реальных сценариях, тогда как для HashMap это маловероятно. Еще одна причина отдать предпочтение HashMapсвыше Hashtable.

  • По какой-то причине Hashtable Enumeration пересекает сегменты в обратном порядке, поэтому добавленные элементы возвращаются в обратном порядке.

5 голосов
/ 06 апреля 2011

Причина такого поведения:

class Properties extends Hashtable<Object,Object>

Таким образом, порядок не поддерживается, просто совпадение, как уже упоминалось axtavt.

5 голосов
/ 06 апреля 2011

Это просто совпадение; свойства фактически возвращаются в неопределенном порядке. «Свойства» - это просто Hashtable; Перечисления Hashtable не возвращают свои ключи в каком-либо определенном порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...