Java使用streams与TreeMap对地图进行排序
考虑以下Java HashMapJava使用streams与TreeMap对地图进行排序,java,dictionary,hashmap,Java,Dictionary,Hashmap,考虑以下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"); Map unsortMap=newhashmap(); unsortMap.put(“Z”,“Z”); 不排序地图
Map<String, String> unsortMap = new HashMap<String, String>();
unsortMap.put("Z", "z");
unsortMap.put("B", "b");
unsortMap.put("A", "a");
unsortMap.put("C", "c");
Map unsortMap=newhashmap();
unsortMap.put(“Z”,“Z”);
不排序地图。放置(“B”、“B”);
不排序地图。放置(“A”、“A”);
不排序映射。放置(“C”、“C”);
现在我想按键对这张地图进行排序。其中一个选择是使用树形图
Map<String, String> treeMap = new TreeMap<String, String>(unsortMap);
Map treeMap=newtreemap(unsortMap);
另一个选项是使用带有Sorted()的Java Streams,如下所示
Map<String, Integer> sortedMap = new HashMap<>();
unsortMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.forEachOrdered(x -> sortedMap.put(x.getKey(), x.getValue()));
Map sortedMap=newhashmap();
unsortMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.forEachOrdered(x->sortedMap.put(x.getKey(),x.getValue());
在这两个选项中,哪一个选项是首选的?为什么(可能是在性能方面)
谢谢流代码甚至不会对映射进行排序,因为它正在对本质上未排序的
哈希映射执行操作。要使第二个流示例正常工作,可以使用LinkedHashMap
,它维护插入顺序:
Map<String, Integer> sortedMap = new LinkedHashMap<>();
unsortMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.forEachOrdered(x -> sortedMap.put(x.getKey(), x.getValue()));
Map sortedMap=newlinkedhashmap();
unsortMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.forEachOrdered(x->sortedMap.put(x.getKey(),x.getValue());
但现在,您的两个示例甚至不是相同的底层数据结构。TreeMap
后面有一棵树(如果我没记错的话,是红黑的)。如果您希望能够以排序方式进行迭代,或者快速搜索关键字,则可以使用树映射。LinkedHashMap
是一个hashmap,其中运行着一个链表。如果您需要维护插入顺序,例如在实现队列时,您可以使用此方法。第二种方法不起作用,当您调用HashMap#put
时,它不保持put顺序。您可能需要LinkedHashMap
树形映射与s.Stream(LinkedHashMap):
代码样式。使用TreeMap更干净,因为您可以在一行中实现它
空间复杂性。如果原始映射是HashMap
,则使用这两种方法,您需要创建一个新的map
。如果原始映射是LinkedHashMap
,则只需使用第一种方法创建一个新的map
。您可以使用第二种方法重复使用LinkedHashMap
时间复杂性。它们都应该有O(nln(n))
正如其他人所指出的,将已排序的条目流转储到常规的HashMap
中不会起任何作用LinkedHashMap
是合乎逻辑的选择
然而,上述方法的一种替代方法是充分利用流采集器
API
collector
有一个toMap
方法,允许您为Map
提供替代实现。因此,您可以要求使用LinkedHashMap
而不是HashMap
,如下所示:
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
));
在使用树形图和LinkedHashMap之间。。。构造的复杂性可能与O(n logn)一样。。。显然,如果您计划继续向树映射添加更多元素,那么TreeMap
解决方案是一种更好的方法。。。在这种情况下,我想你应该从一个TreeMap
开始。LinkedHashMap
选项的优点是,查找将是链接或原始未排序映射上的O(1),而树映射类似于O(logn)
,因此,如果需要保留未排序映射以进行高效查找,而在构建LinkedHashMap时,可以丢弃原始未排序映射(从而节省了一些内存)
为了使LinkedHashMap更高效,您应该在构建时提供所需大小的良好估计器,这样就不需要动态调整大小,因此,您可以使用LinkedHashMap::new
而不是()->new LinkedHashMap(unsortedMap.size())
我认为使用TreeMap
更简洁…因为它可以使代码更小,所以除非有实际的性能问题可以使用未排序和排序的链接映射方法解决,否则我将使用树您的第二个选项实际上不起作用。当然,这应该算不上吗?我对HashMaps和LinkedHashMaps的数据量很低。我从这篇文章中了解到了这一点,这篇文章实际上与上面的评论有着正确的实现,请解释一下哪个选项更好?LinkedHashMap的TreeMap通过streamsApples排序到oranges…它们不是相同的数据结构添加到hashmap中没有任何作用,因为将再次以随机顺序插入数据。@SanathKumar…不确定您的意思…解决方案使用的是LinkedHashMap
而不是常规的HashMap
。我试图解释为什么使用HashMap不起作用。它是为op而不是为您设计的。