我将值放入形式为
的hashmap中Map<Long, Double> highLowValueMap=new HashMap<Long, Double>();
highLowValueMap.put(1l, 10.0);
highLowValueMap.put(2l, 20.0);
我想使用values()
地图方法创建一个列表。
List<Double> valuesToMatch=new ArrayList<>();
valuesToMatch=(List<Double>) highLowValueMap.values();
或
List<Double> valuesToMatch=(List<Double>) highLowValueMap.values();
然而,它引发了一个例外:
线程“main”中的异常java.lang.ClassCastException:
java.util.HashMap $不能将值强制转换为java.util.List
但它允许我将其传递给列表的创建:
List<Double> valuesToMatch = new ArrayList<Double>( highLowValueMap.values());
答案 0 :(得分:113)
List<V> al = new ArrayList<V>(hashMapVar.values());
由于HashMap#values()
返回java.util.Collection<V>
而您无法将Collection
投放到ArrayList
,因此您获得了ClassCastException
。
我建议使用ArrayList(Collection<? extends V>)
构造函数。此构造函数接受一个实现Collection<? extends V>
作为参数的对象。当您传递ClassCastException
的结果时,您将无法获得HashMap.values()
:
List<V> al = new ArrayList<V>(hashMapVar.values());
HashMap#values():检查来源中的返回类型,并问问自己,java.util.Collection
是否可以投放到java.util.ArrayList
?否
public Collection<V> values() {
Collection<V> vs = values;
return (vs != null ? vs : (values = new Values()));
}
ArrayList(Collection):检查源中的参数类型。参数是超类型的方法可以接受子类型吗?是
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
答案 1 :(得分:21)
通过阅读JavaDoc
可以找到答案 values()
方法返回Collection
所以
List<Double> valuesToMatch=(List<Double>) highLowValueMap.values();
应该是
Collection<Double> valuesToMatch= highLowValueMap.values();
您仍然可以像列表一样迭代此集合。
http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html#values%28%29
这有效:
List<Double> valuesToMatch = new ArrayList<Double>( highLowValueMap.values() );
因为ArrayList
有一个接受集合的构造函数。
答案 2 :(得分:5)
这是因为values()
返回Collection
根据HashMap
的源代码属于AbstractCollection
,因此无法转换为List
。
您可以实例化ArrayList
传递values()
结果,因为ArrayList
构造函数可以将Collection
作为参数。
答案 3 :(得分:3)
如果您已经创建了List子类型的实例(例如,ArrayList,LinkedList),则可以使用addAll方法。
如,
valuesToMatch.addAll(myCollection)
许多列表子类型也可以在其构造函数中获取源集合。
答案 4 :(得分:2)
您是否检查了API,values()
方法返回了什么? ArrayList constructor接受什么?
答案 5 :(得分:2)
我遇到了同样的问题,但后来我意识到values()返回Collection,而不是List。 但是我们能够像这样实例化一个新的ArrayList:
列出valuesToMatch = new ArrayList(highLowValueMap.values());
因为ArrayList有一个构造函数,可以将Collection作为参数。
答案 6 :(得分:1)
好吧,因为你的值实际上是一个HashSet。 您可以编写这样的代码来迭代集合:
List<Double> valuesToMatch=new ArrayList<>();
for(Double d : highLowValueMap.values(){
valuesToMatch.put(d);
}
答案 7 :(得分:1)
Values
是HashMap
类中的内部类(请参阅java.util.HashMap$Values
中的$符号)。
HashMap.values()方法将返回Values
类的对象,该对象未实现List
接口。 ClassCastException
也是如此。
这是HashMap中的Values
内部私有类,它没有实现List
接口。甚至AbstractCollection也没有实现List
接口
AbstractCollection
实现Collection
接口。所以无法转换为List
。
private final class Values extends AbstractCollection<V> {
public Iterator<V> iterator() {
return newValueIterator();
}
public int size() {
return size;
}
public boolean contains(Object o) {
return containsValue(o);
}
public void clear() {
HashMap.this.clear();
}
}
<强>更新强>
以下是ArrayList中的构造函数之一。
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
因此hashmapObj.values()
方法返回类型为Collection
。现在哪个类实现了这个Collection接口?答案是Values
类,它位于HashMap类(内部类)中。从hashmapObj.values()
返回的值可以传递给上面有效的ArrayList构造函数。
即使以下是有效的陈述。
HashMap<String, String> map = new HashMap<String, String>();
Collection c = map.values();
但以下陈述不正确
HashMap<String, String> map = new HashMap<String, String>();
List c = map.values(); //compilation error.. return type is not List
答案 8 :(得分:0)
我怀疑所选择的最佳答案,它说: “因为HashMap#values()返回一个java.util.Collection,你不能将一个Collection转换为ArrayList,因此你得到ClassCastException。”
这不是因为Collection无法转换为ArrayList,真正的原因是HashMap.values()返回的Collection由内部类HashMap.Values备份。而HashMap.Values不是ArrayList的超类。
答案 9 :(得分:0)
要将值从 Map 实例转换为列表,您可以使用 Iterable<T>.map
val yourList: List<Any> = #Map.values.map { it }