【问题标题】:Convert a list of objects to a hashmap in Java在 Java 中将对象列表转换为哈希图
【发布时间】:2011-02-04 10:32:47
【问题描述】:

我有一个 java List<Object>,每个对象都是一个包含一个字符串和一个整数的字符串。我无法控制列表,因为它是由 API 方法返回的。

我想将列表转换为地图。最好的方法是什么?

【问题讨论】:

    标签: list hashmap


    【解决方案1】:

    创建一个您喜欢的类型的 Map(HashMap、TreeMap、HashTable...),然后遍历您的列表并一一添加所有元素。

    没有更好的方法(除非您愿意编写由此列表支持的自己的地图,在某些情况下,这会非常好)。

    您可以在添加元素之前在地图类型上设置一些选项(例如设置大小),因为您已经知道要添加多少元素。这可能会稍微提高性能。很大程度上取决于您的用例。

    编辑:我这么说是因为我理解您的问题,因为您的列表包含带有字符串和整数属性的 POJO。如果不同,那么答案可能会不同。

    【讨论】:

    • 没错,在本例中是 POJO 列表。
    【解决方案2】:

    “铸造”,即将列表视为另一种类型的东西是行不通的,除非 API 返回的对象也实现了 Map(它显然没有)。但是您可以根据列表的内容创建地图。

    Furter:列表不能包含<String, Integer>,因为列表只包含一种类型的对象。我想,它包含一个像这样的对象:

    public class Element {
      public String key;
      public Integer value;
    }
    

    对于这样的事情,显而易见的解决方案是这样的:

    Map<String, Integer> map = new HashMap<String, Integer>(list.size()); // the size of the map will be the size of the list.
    for(Element e: list) {
      map.put(e.key, e.value);
    }
    

    如果列表及其条目以后都不会更改,那么这就足够了。如果某些东西可能会发生变化,那么您必须实现自己的地图,对列表进行即时翻译。根据变化,这或多或少有些复杂,但如果一切都可能发生变化,那么您可以创建一个将列表转换为地图的新类:

    class ListTranslatorMap extends AbstractMap<String, Integer> {
    
      private List<Element> list;
    
      public ListTranslatorMap(List<Element> list) {
        this.list = list;
      }
    
      public Set<Map.Entry<String, Integer>> entrySet() {
        return new AbstractSet<Map.Entry<String, Integer>>() {
          public int size() {
            return list.size();
          }
    
          public Iterator<Map.Entry<String, Integer>> iterator() {
            final Iterator<Element> listIterator = list.iterator();
            return new Iterator<Map.Entry<String, Integer>>() {
              public boolean hasNext() {
                return listIterator.hasNext();
              }
    
              public void remove() {
                listIterator.remove();
              }
    
              public Map.Entry<String, Integer> next() {
                final Element element = listIterator.next();
                return new Map.Entry<String, Integer>() {
                  public String getKey() {
                    return element.key;
                  }
                  public Integer getValue() {
                    return element.value;
                  }
                  public Integer setValue(Integer value) {
                    Integer prev = element.value;
                    element.value = value;
                    return prev;
                  }
                };
              }
            };
          }
        };
      }
    
    }
    

    但通常情况下,这将是矫枉过正,简单的翻译 for 循环就足够了。如果您需要更多处理地图的方法 - 或者如果它不是地图,而是带有一个键和多个条目的 Multimap),那么请查看Google Guava 库,它在com.google.common.collect.Maps 中有方便的索引函数.

    【讨论】:

    • 嘿,谢谢您的回答!我认为您的方法也应该可以正常工作
    【解决方案3】:

    循环遍历列表并将它们存储到新地图中:

        Map<String, Integer> result = new HashMap<String, Integer>();
        for(Map<String,Integer> item : list){
            result.putAll(item);
        }
    

    请注意,如果列表中有多个项目具有相同的 String 键,那么它们将在地图中相互覆盖。

    【讨论】:

      【解决方案4】:

      不确定您对 &lt;String, Integer&gt; 的对象是什么意思,但如果这是一个地图,这里是代码:

      Map<String,Integer> map=new Hasmap<String, Integer>();
      for(Object o:list){
        Map<String,Integer> m=(Map<String,Integer>)o
        map.putAll(m)
      }
      

      您可能会因为键覆盖而丢失数据

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-24
        • 1970-01-01
        • 1970-01-01
        • 2015-01-04
        • 1970-01-01
        • 1970-01-01
        • 2011-01-17
        • 2020-09-15
        相关资源
        最近更新 更多