Convert a list of objects to a hashmap in Java
I have a java List<Object>
and each object is a String containing a String and an Integer. I have no control over the List since it is returned by an开发者_StackOverflow社区 API method.
I'd like to cast the List to a Map. What is the best way to do this?
Create a Map of the type you like (HashMap, TreeMap, HashTable,...) and then iterate through your list and add all elements one by one.
There is no better way (except if you are willing to code your own map that is backed by this list which - in some cases - would be really good).
You MAY set some options on your Map type before adding the elements (such as setting the size) because you already know how many elements to add. That may increase performance a little. Depends heavily on your use case.
EDIT: I said this because I understand your question in a way that your lists contains POJOs with a string and an integer attribute. If that's different, then the answer may be different.
"Casting", i.e. treating the list as something of another type won't work unless the object returned by the API also implements Map (which it obviously doesn't). But you can create a Map out of the list's content.
Furter: The list cannot contain <String, Integer>
, as lists only contain objects of one type. I suppose, it contains an object like this:
public class Element {
public String key;
public Integer value;
}
For such things, the obvious solution is as such:
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);
}
If neither the list nor its entries won't change later, then this should suffice. If something can cange, then you must implement your own map that does an on-the-fly translation of the list. Depending on what changes, this is more or less complicated, but if everything is subject to change, then you could create a new class that translates the list into a map:
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;
}
};
}
};
}
};
}
}
But usually, this would be overkill and the simple translating for-loop suffices. If you need more ways of handling maps - or if it isn't a map, but a Multimap with a key and more than one entries), then have a look at the Google Guava libraries which has handy index functions in com.google.common.collect.Maps.
Loop over the list and store them into a new Map:
Map<String, Integer> result = new HashMap<String, Integer>();
for(Map<String,Integer> item : list){
result.putAll(item);
}
Note that if you have multiple items in the list with the same String key, then they will overwrite each other in the map.
Not sure about what you mean about an object being a <String, Integer>
but if this is a Map here is the code:
Map<String,Integer> map=new Hasmap<String, Integer>();
for(Object o:list){
Map<String,Integer> m=(Map<String,Integer>)o
map.putAll(m)
}
you may lose data by key overriding though
精彩评论