【问题标题】:How to convert a Map to List in Java?如何在 Java 中将 Map 转换为 List?
【发布时间】:2018-07-28 09:26:06
【问题描述】:

Map<key,value> 转换为List<value> 的最佳方法是什么?只需遍历所有值并将它们插入列表中还是我忽略了什么?

【问题讨论】:

  • 我认为如果必须将地图转换为列表,这不是一个好模型。应该以不会出现这种情况的方式编写代码。

标签: java list collections map


【解决方案1】:
List<Value> list = new ArrayList<Value>(map.values());

假设:

Map<Key,Value> map;

【讨论】:

  • 谢谢!我假设从CollectionList 的演员阵容会起作用。
  • 我怀疑它不起作用的原因是因为 values() 返回的集合依赖于底层 Map;相反,通过调用复制构造函数,您可以分配存储空间并将值复制到该存储空间中,从而中断连接...
  • 如果我们有 LinkedHashMap - 订单会保持不变吗?
  • @user2022068 是的,应该使用 LinkedHashMap 保留订单。
  • @SheldonR。是的 - keySet()values() 返回的集合通常是 shim 对象,它们提供底层结构的 Set 或 Collection 视图(keySet() 返回一个 Set 以强调没有欺骗)。对于values(),返回的对象可能List,但通常不会。正如您所说,创建一个真正的列表会破坏链接,这意味着您不再依赖于原始地图。但有时,您只需要一个 List,因为某些 API 需要一个 - 强化了一个规则,即一个好的 API 应该只需要它可以摆脱的最抽象的接口......
【解决方案2】:

一份清单?

假设map 是您的Map 实例

  • map.values() 将返回一个包含所有地图值的 Collection
  • map.keySet() 将返回一个包含地图所有键的 Set

【讨论】:

    【解决方案3】:

    这里的问题是Map 有两个值(键和值),而List 只有一个值(一个元素)。

    因此,最好的办法是获取键或值的List。 (除非我们制作一个包装器来保存键/值对)。

    假设我们有一个Map

    Map<String, String> m = new HashMap<String, String>();
    m.put("Hello", "World");
    m.put("Apple", "3.14");
    m.put("Another", "Element");
    

    可以通过从Set 方法返回的Set 创建一个新的ArrayList 来获得List 形式的密钥:

    List<String> list = new ArrayList<String>(m.keySet());
    

    虽然可以通过Map.values 方法返回的Collection 创建一个新的ArrayList,但可以获得List 形式的值:

    List<String> list = new ArrayList<String>(m.values());
    

    得到List的keys的结果:

    苹果 其他 你好

    得到List的值的结果:

    3.14 元素 世界

    【讨论】:

    • 应该注意,这些方法返回的值的顺序是未定义,对于HashMap 和类似的未排序Map 实现,它实际上是随机的.
    • 是的,您必须知道它是 LinkedHashMap 或类似的东西。原始问题的问题在于问题陈述错误,即需要编辑。问题不是将 Map 转换为 List,而是如何将 Map 的值作为 List 获取。方法值给你一个集合,但不是一个列表,因此需要一个巧妙的小技巧。
    • 我认为您可以在答案中添加@M0les 所说的内容:您需要以某种方式“通过”SortedMap。要么从具体的 SortedMap 实现开始(例如 TreeMap),要么将输入 Map 插入到 SortedMap 中,然后再将其转换为 List
    【解决方案4】:

    我猜您想将Map 中包含的值转换为list?最简单的是调用Map接口的values()方法。这将返回 Map 中包含的值对象的 Collection

    请注意,此CollectionMap 对象支持,对Map 对象的任何更改都将反映在此处。因此,如果您想要一个不绑定到 Map 对象的单独副本,只需创建一个新的 List 对象,如 ArrayList 传递值 Collection,如下所示。

    ArrayList<String> list = new ArrayList<String>(map.values());
    

    【讨论】:

      【解决方案5】:

      map.entrySet() 为您提供包含键和值的 Map.Entry 对象的集合。然后您可以将其转换为您喜欢的任何集合对象,例如new ArrayList(map.entrySet());

      【讨论】:

        【解决方案6】:

        如果要确保结果 List&lt;Value&gt; 中的值在输入 Map&lt;Key, Value&gt; 的键顺序中,则需要以某种方式“通过”SortedMap

        开始使用具体的SortedMap 实现(例如TreeMap)或将您的输入Map 插入SortedMap,然后再将其转换为List。例如:

        Map<Key,Value> map;
        List<Value> list = new ArrayList<Value>( new TreeMap<Key Value>( map ));
        

        否则,您将获得 Map 实现提供的任何本机排序,这通常可能不是自然键排序(尝试HashtableConcurrentHashMap,以获得多样性)。

        【讨论】:

          【解决方案7】:
              Map<String, Integer> map = new HashMap<String, Integer>();
              map.put("java", 20);
              map.put("C++", 45);
          
              Set <Entry<String, Integer>> set = map.entrySet();
          
              List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);
          

          我们可以在列表中同时拥有键和值对。也可以使用 Map.Entry 通过迭代列表来获取键和值。

          【讨论】:

            【解决方案8】:

            你可以这样做

            List<Value> list = new ArrayList<Value>(map.values());
            

            【讨论】:

            • OP 询问如何转换成 List。提供答案时,最好在建议的解决方案中包含一个良好的描述。此问题已被接受回答。
            【解决方案9】:

            使用 Java 8 Streams API。

            List<Value> values = map.values().stream().collect(Collectors.toList());
            

            【讨论】:

            • 我更喜欢接受的、基于构造函数的答案。流应该用于简化代码。
            • @Aaron 是的,对于从 Map 获取值列表的任务,构造函数似乎更简单。但是,如果您在代码库中广泛使用 Streams,最好保持一致。
            • 当我使用它时,如果我正在获取大量数据,则会出现错误。线程在 java.util.stream.ReduceOps$3.makeSink(Unknown Source) 上循环。如果线程无限循环,CPU 消耗将开始飙升。循环线程堆栈跟踪如下,检查它
            【解决方案10】:
             Map<String, String > map = new HapshMap<String, String>;
             map.add("one","java");
             map.add("two", "spring");
             Set<Entry<String, String>> set = map.entrySet();
             List<Entry<String, String>> list = new ArrayList<Entry<String, String>>    (set);
             for(Entry<String, String> entry : list) {
               System.out.println(entry.getKey());
               System.out.println(entry.getValue());
             }
            

            【讨论】:

              【解决方案11】:
              HashMap<Integer, List<String>> map = new HashMap<>(); 
              List<String> list = new ArrayList<String>();
              list.add("Java");
              list.add("Primefaces");
              list.add("JSF");
              map.put(1,list);
              if(map != null){
                  return new ArrayList<String>((Collection<? extends String>) map.values());
              }
              

              【讨论】:

                【解决方案12】:

                这是从地图获取值的通用方法。

                public static <T> List<T> ValueListFromMap(HashMap<String, T> map) {
                    List<T> thingList = new ArrayList<>();
                
                    for (Map.Entry<String, T> entry : map.entrySet()) {
                        thingList.add(entry.getValue());
                    }
                
                    return thingList;
                }
                

                【讨论】:

                  【解决方案13】:
                  // you can use this
                  List<Value> list = new ArrayList<Value>(map.values());
                  
                  // or you may use 
                  List<Value> list = new ArrayList<Value>();
                  for (Map.Entry<String, String> entry : map.entrySet())
                  {
                  list.add(entry.getValue());    
                  }
                  

                  【讨论】:

                    【解决方案14】:

                    如果你想要一个 不可变 值的副本:

                    List<Value> list = List.copyOf(map.values())
                    

                    【讨论】:

                    • 你为什么不提List.copyOf的包?
                    • 因为是平常的java.util.List?
                    • 什么?但仅弹出 .class java.util.List.class
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-02-23
                    • 1970-01-01
                    • 2017-07-14
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-11-20
                    • 2013-07-22
                    相关资源
                    最近更新 更多