【问题标题】:How do i create an arraylist of values from a nested HashMap in java?如何从 Java 中的嵌套 HashMap 创建值的数组列表?
【发布时间】:2019-12-07 23:04:33
【问题描述】:

我已经使用嵌套的 HashMap 编写了我的代码,我试图弄清楚如何将内部映射的键指向的所有值放入 ArrayList 中,以便对其进行正确排序。 我的地图是这样的:

HashMap<String, HashMap<String, Double>> vlist;

我的想法是创建另一个与之前显示的内部映射具有相同键和值的 HashMap, 然后以这种方式填充它。

HashMap<String, Double> vlistValues = new HashMap<>(vlist.values());

我得到一个编译错误,我可以弄清楚编译器不知道我的外部映射的值是一个映射本身,但是阅读 hashmap 文档我没有找到适合我的情况的方法。

基本上我想把这里声明的内部映射的所有值HashMap&lt;String ,HashMap&lt;String, Double&gt;&gt; vlist; 放到像这样ArrayList&lt;Double&gt; listOfValues; 这样的列表中

如果不清楚我对编程完全陌生:-)

我将展示一个示例: 我的地图HashMap&lt;String, Hashmap&lt;String,Double&gt;&gt; 表示加权图的邻接列表。我需要对所有边进行排序(因为我正在尝试实现 Kruskal 算法),我的想法是将所有权重放在一个列表中,执行如下操作:

ArrayList<String> vertexList; //all the vertices of the graph
ArrayList<Double> weights; 
HashMap<String, String> orderedEdges = new HashMap<>(); //here i put ordered edges
double min = Collections.min(weights); //i use this double to keep track of the minimum element in weights

  for(String vertex1 : vertexlist){
    makeSet(vertex1);
    for(String vertex2 : ajacents(vertex1)){
      if(getEdgeWeight(v1,v2) <= min){ //method "getEdgeWeight" is to retrieve weight of an edge
        orderedEdges.put(v1,v2);
        min = getEdgeWeight(v1,v2) 
        weights.remove(min) //i'm not sure this line is correct
      }
    }
  }

在线查看一些伪代码,我看到它能够制作不相交的集合并在同一个 for 循环中对边进行排序。可能我的代码效率不高,但我真的不知道如何在不访问所有图形的情况下对边缘进行排序。 Ps 我不能使用优先队列,但我完全知道我正在尝试做的是类似的事情

【问题讨论】:

  • 你现在可以考虑接受一个答案 ;) 来奖励那些为你花时间的人 ;)

标签: java arraylist collections hashmap kruskals-algorithm


【解决方案1】:

所以你说:

基本上我想把这里声明的内部映射的所有值HashMap&lt;String ,HashMap&lt;String, Double&gt;&gt; vlist;到这样的列表ArrayList&lt;Double&gt; listOfValues

这是示例 hashMap。

      Map<String, Map<String, Double>> mm = Map.of("A",
            Map.of("R", 1.2, "S", 3.4, "T", 3.8),
            "B",
            Map.of("S", 9.8, "V", 2.8),
            "Z",
            Map.of("P", 22.3));

      System.out.println(mm);

这是地图。

{Z={P=22.3}, B={S=9.8, V=2.8}, A={T=3.8, S=3.4, R=1.2}}

要转换为双打的List,您可以这样做。获取valuesstream(它们是内部映射),然后通过flatMapcombine all the values in those maps 放入公共流中,然后收集到List

      List<Double> dubs =
            mm.values().stream().flatMap(k -> k.values().stream()).collect(
                  Collectors.toList());

      System.out.println(dubs);

这是清单。

[22.3, 9.8, 2.8, 3.8, 3.4, 1.2]

如果你想要一个Map&lt;String, List&lt;Doubles&gt;&gt;,其中字符串是外部 Map 的键,你可以这样做。创建entrySetentrySetstream 并将其传递给collectorcollector 使用 outer maps key 创建一个映射,然后获取 inner map(它是一个集合)的值并将它们作为参数传递给 ArrayList&lt;&gt; 以创建一个 List

  Map<String, List<Double>> mapOfDubs =
        mm.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(),
              e -> new ArrayList<>(e.getValue().values())));

  System.out.println(mapOfDubs);

这是地图。

{A=[1.2, 3.4, 3.8], B=[2.8, 9.8], Z=[22.3]}

【讨论】:

    【解决方案2】:

    从像 HashMap&lt;String, HashMap&lt;String, Double&gt;&gt; vlist; 这样的地图你有

    • vlist.keys() 一个 List&lt;String&gt; ,其中包含所有密钥
    • vlist.values() 一个List&lt;HashMap&lt;String, Double&gt;&gt;,其中包含所有作为值的地图

    要获得特定的List&lt;Double&gt;,您需要一个密钥,因此请选择您将从中读取双打的内部地图

    HashMap<String, HashMap<String, Double>> outer = ...; // don't call a map *list*
    HashMap<String, Double> inner  = outer.get("mykey");
    List<Double> values = new ArrayList<>(inner.values()); // as values() returns a Collection
    

    【讨论】:

    • 好的,谢谢,所以我需要一个特定的键,或者我可以为内部映射中的每个键做它?
    • @flatbrain 似乎你不了解结构,外部映射的键指向映射,内部映射的键指向 Double 值,只有一个,也许你可以编辑你的用一个例子的帖子来解释更多?此外,“编程新手”也不太适合“访问嵌套映射中的值”;)
    猜你喜欢
    • 2020-04-04
    • 1970-01-01
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-27
    • 1970-01-01
    相关资源
    最近更新 更多