考虑以下Java HashMap。
Map<String, String> unsortMap = new HashMap<String, String>();
unsortMap.put("Z", "z");
unsortMap.put("B", "b");
unsortMap.put("A", "a");
unsortMap.put("C", "c");
现在,我希望按“关键字”对该地图进行排序。一种选择是让我为此目的使用TreeMap。
Map<String, String> treeMap = new TreeMap<String, String>(unsortMap);
另一个选择是让我将Java流与Sorted()一起使用,如下所示。
Map<String, Integer> sortedMap = new HashMap<>();
unsortMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.forEachOrdered(x -> sortedMap.put(x.getKey(), x.getValue()));
在这两个选项中,哪个选项更可取,为什么(在性能方面)?
谢谢
答案 0 :(得分:2)
正如其他人指出的那样,将已排序的条目流转储到常规HashMap
中将无济于事……LinkedHashMap
是合乎逻辑的选择。
但是,上述方法的替代方法是充分利用Stream Collectors
API。
Collectors
具有toMap
方法,可让您为Map
提供替代实现。因此,您可以像这样要求HashMap
来代替LinkedHashMap
:
unsortedMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(v1, v2) -> v1, // you will never merge though ask keys are unique.
LinkedHashMap::new
));
在使用TreeMap和LinkedHashMap之间...构造的复杂性可能类似于O(n log n)...显然,TreeMap
解决方案是一个更好的方法,如果您打算保留在其中添加更多元素...在这种情况下,我想您应该以{{1}}开始。 TreeMap
选项的优势在于,在链接或原始未排序的地图上查找将为O(1),而TreeMap的查找类似于LinkedHashMap
,因此如果您需要保留未排序的地图进行高效查找,而如果您构建LinkedHashMap,则可以扔掉原始的未排序地图(从而节省一些内存)。
要使O(log n)
的工作效率更高,您应该在构造时提供所需大小的良好估算器,这样就不需要动态调整大小,因此您可以说{{{ 1}}。
我认为LinkedHashMap
的使用更加简洁...因为可以使代码更小,因此除非存在实际的性能问题,否则可以使用我将使用的未排序和排序的链接映射方法来解决LinkedHashMap::new
。
答案 1 :(得分:1)
您的流代码甚至不会对地图进行排序,因为它是针对HashMap
执行操作的,而LinkedHashMap
本质上是未排序的。为了使第二个流示例正常工作,您可以使用Map<String, Integer> sortedMap = new LinkedHashMap<>();
unsortMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.forEachOrdered(x -> sortedMap.put(x.getKey(), x.getValue()));
,它可以保持插入顺序:
TreeMap
但是现在您的两个示例甚至都不是相同的基础数据结构。 TreeMap
由树支持(如果我没记错的话,它是红色的黑色)。如果您希望能够以排序的方式进行迭代或快速搜索密钥,则可以使用LinkedHashMap
。 var foodNotPlaced;
snake.forEach(function(segment) {
if (food.x != segment.x and food.y != segment.y) {
ctx.fillStyle = 'red';
ctx.fillRect(food.x, food.y, unit, unit);
foodNotPlaced = false;
}
else {
food.x = Math.floor(Math.random()*((cvsW/unit)-1)+1)*unit;
food.y = Math.floor(Math.random()*((cvsW/unit)-1)+1)*unit;
foodNotPlaced = True;
});
是哈希表,其中贯穿有一个链表。如果您需要保持插入顺序(例如在实施队列时),则可以使用它。
答案 2 :(得分:1)
第二种方法不起作用,当您调用LinkedHashMap
时,它不保留看跌订单。您可能需要HashMap
。
TreeMap诉流(LinkedHashMap):
Map
,则使用这两种方法都需要创建一个新的LinkedHashMap
。如果原始地图为Map
,则只需使用第一种方法创建一个新的LinkedHashMap
。您可以通过第二种方法重复使用gem install
。