为什么哈希映射值不在列表中转换?TL;DR解释进一步了解 Java API 源代码

2022-08-31 11:28:39

我将值放入哈希图中,其形式为,

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());

答案 1

TL;DR

List<V> al = new ArrayList<V>(hashMapVar.values());

解释

因为返回 a 并且你不能将 a 转换为 a,因此你会得到 。HashMap#values()java.util.Collection<V>CollectionArrayListClassCastException

我建议使用构造函数。此构造函数接受作为参数实现的对象。当你通过这样的结果时,你不会得到:ArrayList(Collection<? extends V>)Collection<? extends V>ClassCastExceptionHashMap.values()

List<V> al = new ArrayList<V>(hashMapVar.values());

进一步了解 Java API 源代码

HashMap#values():检查源中的返回类型,并问自己,是否可以将 a 转换为 ?不java.util.Collectionjava.util.ArrayList

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

数组列表(集合):检查源中的参数类型。参数为超类型的方法是否可以接受子类型?是的

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);
}

答案 2

答案可以通过阅读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