【发布时间】:2011-02-04 10:32:47
【问题描述】:
我有一个 java List<Object>,每个对象都是一个包含一个字符串和一个整数的字符串。我无法控制列表,因为它是由 API 方法返回的。
我想将列表转换为地图。最好的方法是什么?
【问题讨论】:
我有一个 java List<Object>,每个对象都是一个包含一个字符串和一个整数的字符串。我无法控制列表,因为它是由 API 方法返回的。
我想将列表转换为地图。最好的方法是什么?
【问题讨论】:
创建一个您喜欢的类型的 Map(HashMap、TreeMap、HashTable...),然后遍历您的列表并一一添加所有元素。
没有更好的方法(除非您愿意编写由此列表支持的自己的地图,在某些情况下,这会非常好)。
您可以在添加元素之前在地图类型上设置一些选项(例如设置大小),因为您已经知道要添加多少元素。这可能会稍微提高性能。很大程度上取决于您的用例。
编辑:我这么说是因为我理解您的问题,因为您的列表包含带有字符串和整数属性的 POJO。如果不同,那么答案可能会不同。
【讨论】:
“铸造”,即将列表视为另一种类型的东西是行不通的,除非 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 中有方便的索引函数.
【讨论】:
循环遍历列表并将它们存储到新地图中:
Map<String, Integer> result = new HashMap<String, Integer>();
for(Map<String,Integer> item : list){
result.putAll(item);
}
请注意,如果列表中有多个项目具有相同的 String 键,那么它们将在地图中相互覆盖。
【讨论】:
不确定您对 <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)
}
您可能会因为键覆盖而丢失数据
【讨论】: