【问题标题】:Can't convert tuple list to hashmap java无法将元组列表转换为 hashmap java
【发布时间】:2019-03-29 09:37:16
【问题描述】:

我想将javax.persistence.Tuple 转换为HashMap,但是像这样,它插入了元组的最后一个元素,并且还采用了别名和数据类型。如何改进此方法以获取元组的值?

public Map<String, Object> tuplesToMap(List<Tuple> data){
    Map<String, Object> values = new HashMap<>();
    data.forEach(tuple -> {
        tuple.getElements().forEach(
            element -> {
                values.put(element.getAlias(), tuple.get(element));
            }
        );
    });
    return values;
}

【问题讨论】:

  • 你在谈论 javax.persistence.Tuple,不是吗?
  • @luca.vercelli 是的

标签: java hashmap tuples


【解决方案1】:

使用 java 8 很简单:

return data.stream()
    .collect(Collectors.toMap(
        t -> t.get(0, String.class),
        t -> t.get(1, Object.class)));

【讨论】:

    【解决方案2】:

    似乎正在工作:

    public static List<Map<String/*UPPERCASE*/, Object>> jpaTuplesToMaps(
      List<javax.persistence.Tuple> data
    ){
        return data.stream()
            .map(tuple -> { // per each tuple of the input List
                // creating a new HashMap
                Map<String, Object> resultItem =  new HashMap<>();
                // filling the created HashMap with values of
                tuple.getElements().forEach( // each column of the tuple
                    col -> { resultItem.put(col.getAlias(), tuple.get(col)); } 
                );
                // returning the created HashMap instead of  the current Tuple
                return resultItem;
            })
             // collecting & returning all the created HashMap-s as a List
            .collect(Collectors.toList());
    }
    

    但通常需要单个和列表转换,所以让我们将它们组合起来:

    public static Map<String/*UPPERCASE*/, Object> jpaTupleToMap(
        javax.persistence.Tuple data /*CASE INSENSITIVE*/
    ){
        Map<String, Object> result = 
            new HashMap<>(); // exactly HashMap since it can handle NULL keys & values
        data.getElements().forEach(
            col -> { result.put(col.getAlias(), data.get(col)); } 
        );
        return result;
    }
    
    //-------------------------
        
    public static List<Map<String/*UPPERCASE*/, Object>> jpaTuplesToMaps(
        List<javax.persistence.Tuple> data /*CASE INSENSITIVE*/
    ){
        return data.stream() // List<Tuple> -> Tuple1,..TupleN
            .map(tuple -> jpaTupleToMap(tuple)) // Tuple1 -> HashMap1,..TupleN -> HashMapN
            .collect(Collectors.toList()); // HashMap1,..HashMapN -> List
    }
    
    

    【讨论】:

      【解决方案3】:

      您用作哈希映射键的element.getAlias() 可能与某些元素相同。

      Map 键是唯一的,这意味着,如果您插入条目 (1, "one") 然后 (1, "two"),则第一个值将被后者覆盖。如果您想将多个值映射到一个键,请使用 Map&lt;String, Collection&lt;Object&gt;&gt; 或 Guava 中的 Multimap,这完全一样。

      您可以使用此功能插入到多地图中 - 如果密钥不在地图中,则创建一个新的ArrayList 并将其添加到地图中,否则返回现有的。然后,将值插入到列表中:

      values
          .computeIfAbsent(element.getAlias, k -> new ArrayList<>())
          .add(tuple.get(element));
      

      【讨论】:

      • 如果我这样做,我会得到 tuple.get(element) 的不兼容类型
      • 是的,您还需要创建放置元素的集合 - 您将地图中的值从 Object 更改为 Collection&lt;Object&gt;
      • 当然,您可以这样做,在这种情况下,您将使用 List&lt;Map&lt;String, Object&gt;&gt; 而不是 Map&lt;String, List&lt;Object&gt;&gt; - 请记住,映射键是唯一的,由您来确保您不会覆盖现有的映射。
      • 我同意@OndraK。我只是强调List&lt;Tuple&gt; 实际上是一个矩阵,或者也是一个表。所以将其转换为Map&lt;String, Object&gt; 是不合理的,它是表格的单行。改成List&lt;Map&lt;String, Object&gt;&gt;比较合理。
      猜你喜欢
      • 1970-01-01
      • 2016-07-09
      • 1970-01-01
      • 2014-12-13
      • 2014-02-21
      • 2015-02-13
      • 2016-09-28
      • 1970-01-01
      相关资源
      最近更新 更多