为什么HashMap值不在List中强制转换?

bNd*_*bNd 69 java collections arraylist hashmap

我将值放入形式的hashmap中,

Map<Long, Double> highLowValueMap=new HashMap<Long, Double>();
highLowValueMap.put(1l, 10.0);
highLowValueMap.put(2l, 20.0);
Run Code Online (Sandbox Code Playgroud)

我想用values()map方法创建一个列表.

List<Double> valuesToMatch=new ArrayList<>();
valuesToMatch=(List<Double>) highLowValueMap.values();
Run Code Online (Sandbox Code Playgroud)

要么

List<Double> valuesToMatch=(List<Double>) highLowValueMap.values();
Run Code Online (Sandbox Code Playgroud)

但是,它会引发异常:

线程"main"中的异常java.lang.ClassCastException:
java.util.HashMap $不能将值强制转换为java.util.List

但它允许我将其传递给列表的创建:

List<Double> valuesToMatch  = new ArrayList<Double>( highLowValueMap.values());
Run Code Online (Sandbox Code Playgroud)

Per*_*ror 118

TL; DR

List<V> al = new ArrayList<V>(hashMapVar.values());
Run Code Online (Sandbox Code Playgroud)

说明

因为HashMap#values()返回a 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());
Run Code Online (Sandbox Code Playgroud)

进一步了解Java API源代码

HashMap#values():检查源代码中的返回类型,并问自己,是否可以java.util.Collection进入java.util.ArrayList?没有

public Collection<V> values() {
    Collection<V> vs = values;
    return (vs != null ? vs : (values = new Values()));
}
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)


cow*_*wls 22

通过阅读JavaDoc可以找到答案

values()方法返回一个Collection

所以

List<Double> valuesToMatch=(List<Double>) highLowValueMap.values();
Run Code Online (Sandbox Code Playgroud)

应该

Collection<Double> valuesToMatch= highLowValueMap.values();
Run Code Online (Sandbox Code Playgroud)

您仍然可以像列表一样迭代此集合.

http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html#values%28%29


这有效:

List<Double> valuesToMatch  = new ArrayList<Double>( highLowValueMap.values() );
Run Code Online (Sandbox Code Playgroud)

因为ArrayList有一个接受集合的构造函数.


小智 5

如果您已经创建了 List 子类型的实例(例如,ArrayList、LinkedList),则可以使用 addAll 方法。

例如,

valuesToMatch.addAll(myCollection)
Run Code Online (Sandbox Code Playgroud)

许多列表子类型还可以在其构造函数中获取源集合。


And*_*nov 5

这是因为根据源代码values()返回的类型因此无法转换.CollectionHashMapAbstractCollectionList

您可以实例化ArrayList传递values()结果,因为ArrayList构造函数可以将Collection其作为参数.