treemap 了解
treeMap 一直出现在各种算法中,可是我每次都很难记得清它的用法,所以来一个笔记,让自己了解的更清楚点
lowerKey()方法用于返回严格小于给定键(作为参数传递)的最大键。用简单的话来说,此方法用于查找作为参数传递的元素之后的下一个最大元素。
// create an empty TreeMap
TreeMap<Integer, String>
numMap = new TreeMap<Integer, String>();
// Insert the values
numMap.put(6, "Six");
numMap.put(1, "One");
numMap.put(5, "Five");
numMap.put(3, "Three");
numMap.put(8, "Eight");
numMap.put(10, "Ten");
// Print the Values of TreeMap
System.out.println("TreeMap: " + numMap.toString());
// Get the greatest key mapping of the Map
// As here 9 is not available it returns 8
// because 9 is strictly less than 11, present
System.out.print("Lower Key Entry of Element 9 is: ");
System.out.println(numMap.lowerKey(9));
// Though, 3 is available in the Map
// it returns 1 because this method returns
// strictly less than key according to the specified key
System.out.print("Lower Key Entry of Element 3 is: ");
System.out.println(numMap.lowerKey(3));
Lower Key Entry of Element 9 is: 8
Lower Key Entry of Element 3 is: 1
floorKey()方法用于从参数中返回小于或等于给定键的最大键。
// create an empty TreeMap
TreeMap<Integer, String> numMap = new TreeMap<Integer, String>();
// Insert the values
numMap.put(6, "Six");
numMap.put(1, "One");
numMap.put(5, "Five");
numMap.put(3, "Three");
numMap.put(8, "Eight");
numMap.put(10, "Ten");
// Print the Values of TreeMap
System.out.println("TreeMap: " + numMap.toString());
// Get the greatest key mapping of the Map
// As here 11 is not available it returns 10
// because ten is less than 11
System.out.print("Floor Entry of Element 11 is: ");
System.out.println(numMap.floorKey(11));
// This will give null
System.out.print("Floor Entry of Element 0 is: ");
System.out.println(numMap.floorKey(0));
}
Floor Entry of Element 11 is: 10
Floor Entry of Element 0 is: null
HashMap
同时遍历 key 和 value 时,keySet 与 entrySet 方法的性能差异取决于 key 的具体情况,
如复杂度(复杂对象)、离散度、冲突率等。换言之,取决于 HashMap 查找 value 的开销。
entrySet 一次性取出所有 key 和 value 的操作是有性能开销的,当这个损失小于 HashMap 查找 value 的开销时,entrySet 的性能优势就会体现出来。
当 key 是最简单的数值字符串时,keySet 可能反而会更高效,耗时比 entrySet 少 10%。
总体来说还是推荐使用 entrySet。因为当 key 很简单时,其性能或许会略低于 keySet,但却是可控的;而随着 key 的复杂化,entrySet 的优势将会明显体现出来。当然,我们可以根据实际情况进行选择
只遍历 key 时,keySet 方法更为合适,因为 entrySet 将无用的 value 也给取出来了,浪费了性能和空间。在上述测试结果中,keySet 比 entrySet 方法耗时少 23%。
只遍历 value 时,使用 vlaues 方法是最佳选择,entrySet 会略好于 keySet 方法。
在不同的遍历写法中,推荐使用如下写法,其效率略高一些:
for (String key : map.keySet()) {
value = map.get(key);
}
for (Entry<String, String> entry: map.entrySet()) {
key = entry.getKey();
value = entry.getValue();
}
for (String value : map.values()) {
}
TreeMap
同时遍历 key 和 value 时,与 HashMap 不同,entrySet 的性能远远高于 keySet。这是由 TreeMap 的查询效率决定的,
也就是说,TreeMap 查找 value 的开销较大,明显高于 entrySet 一次性取出所有 key 和 value 的开销。因此,遍历 TreeMap 时强烈推荐使用 entrySet 方法。
只遍历 key 时,keySet 方法更为合适,因为 entrySet 将无用的 value 也给取出来了,浪费了性能和空间。在上述测试结果中,keySet 比 entrySet 方法耗时少 24%。
只遍历 value 时,使用 vlaues 方法是最佳选择,entrySet 也明显优于 keySet 方法。