Java使用streams与TreeMap对地图进行排序

Java使用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”); 不排序地图

考虑以下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”);
不排序地图。放置(“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而不是为您设计的。