#java #properties
#java #свойства
Вопрос:
В моем проекте я использую некоторый файл свойств. Я заметил странное поведение 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
Кто-нибудь может сказать, в чем причина? Спасибо.
Редактировать:
Поскольку ключ хэш-таблицы имеет вид 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());
}
Ответ №1:
Это совпадение. Properties
не гарантирует какого-либо определенного порядка элементов, поэтому порядок может быть произвольным.
Более конкретно, следующие детали реализации приводят к такому поведению:
-
Поскольку ваши ключи отличаются только последней буквой, их хэш-коды (созданные
String.hashCode()
) отличаются только несколькими последними битами. -
Properties
является подклассомHashtable
. В отличие отHashMap
,HashTable
не применяет дополнительную хэш-функцию для смешивания битов хэш-кода. ПосколькуHashtable
для размещения элементов используются последние биты хэш-кода в виде нескольких хэш-сегментов, ваши элементы помещаются в последующие сегменты. Это действительно интересный момент — это означает, что эта реализацияHashtable
может показать наихудшую производительность в некоторых реальных сценариях, тогда как дляHashMap
это маловероятно. Еще одна причина отдать предпочтениеHashMap
вместоHashtable
. -
По какой-то причине
Hashtable
‘sEnumeration
выполняет обход сегментов в обратном порядке, таким образом, добавленные элементы возвращаются в обратном порядке.
Комментарии:
1. Спасибо за ваше замечательное объяснение. Я действительно ценю вашу помощь.
Ответ №2:
Это просто совпадение; свойства фактически возвращаются в неопределенном порядке. «Properties» — это просто хеш-таблица; Перечисления в хеш-таблице не возвращают свои ключи в каком-либо определенном порядке.
Ответ №3:
Причиной такого поведения является:
class Properties extends Hashtable<Object,Object>
Таким образом, порядок не поддерживается, просто совпадение, как уже упоминал axtavt.