In my project I am using some Properties file. I have noticed strange behaviour of Properties.propertyNames(), it returns an Enumeration, that Enumeration is in reverse order. I did a test: The file content is:
TT.1=Development
TT.2=Application Setup / Release
TT.3=Project Management
TT.4=Meetings and Discussions
The code is:
Enumeration<?> enumeration = properties.propertyNames();
while (enumeration.hasMoreElements()) {
String key = (String) enumeration.nextElement();
String value = properties.getProperty(key);
System.out.println(key + " " + value);
}
The output is:
TT.4 Application Setup / Release
TT.3 Development
TT.2 Meetings and Discussions
TT.1 Project Management
Can anyone tell what is the reason behind? Thank you.
Edit: As the Key of the HashTable is of the form TT.X where X is a number I sorted it to make the right order. Here is the next implementation: 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()) {
St开发者_开发技巧ring 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());
}
It's a coincidence. Properties
doesn't guarantee any particular order of elements, so the order can be arbitrary.
More specifically, the following implementation details lead to this behaviour:
Since your keys differ only in the last letter, their hashcodes (produced by
String.hashCode()
) differ only in the last several bits.Properties
is a subclass ofHashtable
. UnlikeHashMap
,HashTable
doesn't apply a supplemental hash function to mix bits of hashcode. SinceHashtable
uses the last bits of hashcode as a number of hash bucket to place the elements, your elements are placed into the consequent buckets. It's a really interesting point - it means that this implementation ofHashtable
can show a worst case performance in some real-world scenarios, whereas forHashMap
it's unlikely. Yet another reason to favorHashMap
overHashtable
.For some reason
Hashtable
'sEnumeration
traverses buckets in reverse order, thus added elements are returned in reverse order.
It's just a coincidence; the properties are actually returned in an undefined order. "Properties" is just a Hashtable; Hashtable enumerations do not return their keys in any particular order.
The reason behind the behaviour is:
class Properties extends Hashtable<Object,Object>
So there is no order maintained, just an coincidence as axtavt already mentioned.
精彩评论