在我的项目中,我正在使用一些属性文件。我注意到了Properties.propertyNames()的奇怪行为,它返回一个Enumeration,Enumeration的顺序相反。我做了一个测试: 文件内容为:
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());
}
答案 0 :(得分:9)
这是巧合。 Properties
不保证元素的任何特定顺序,因此顺序可以是任意的。
更具体地说,以下实现细节会导致此行为:
由于您的密钥仅在最后一个字母中有所不同,因此它们的哈希码(由String.hashCode()
生成)仅在最后几位中有所不同。
Properties
是Hashtable
的子类。与HashMap
不同,HashTable
不应用补充哈希函数来混合哈希码的位。由于Hashtable
使用哈希码的最后几位作为一些哈希桶来放置元素,因此您的元素将被放入随后的桶中。 这是一个非常有趣的观点 - 这意味着Hashtable
的这种实现可以在某些真实场景中显示最差的情况,而HashMap
则不太可能。还有另一个原因支持HashMap
优先于Hashtable
。
由于某种原因,Hashtable
的{{1}}以相反的顺序遍历存储桶,因此添加的元素将以相反的顺序返回。
答案 1 :(得分:5)
这只是一个巧合;这些属性实际上是以未定义的顺序返回的。 “属性”只是一个Hashtable; Hashtable枚举不会以任何特定顺序返回其键。
答案 2 :(得分:5)
行为背后的原因是:
class Properties extends Hashtable<Object,Object>
所以没有维持秩序,只是已经提到过的巧合。