将对象列表转换为Java中的hashmap

时间:2011-02-04 10:32:47

标签: list hashmap

我有一个java List<Object>,每个对象都是一个包含String和Integer的String。我无法控制List,因为它是由API方法返回的。

我想将List转换为Map。这样做的最佳方式是什么?

4 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:2)

“Casting”,即将列表视为另一种类型的东西将不起作用,除非API返回的对象也实现了Map(显然它没有)。但是你可以从列表的内容中创建一个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库中具有便捷索引函数的库{ {3}}

答案 2 :(得分:0)

循环列表并将其存储到新地图中:

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

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

答案 3 :(得分:0)

不确定您对<String, Integer>对象的意思,但如果这是一个地图,则代码为:

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

您可能会因密钥覆盖而丢失数据