Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么HashMap值不在列表中强制转换?_Java_Arraylist_Collections_Hashmap - Fatal编程技术网

Java 为什么HashMap值不在列表中强制转换?

Java 为什么HashMap值不在列表中强制转换?,java,arraylist,collections,hashmap,Java,Arraylist,Collections,Hashmap,我把值放到hashmap中,它的形式是 Map<Long, Double> highLowValueMap=new HashMap<Long, Double>(); highLowValueMap.put(1l, 10.0); highLowValueMap.put(2l, 20.0); 或 List valueToMatch=(List)highLowValueMap.values(); 但是,它会引发一个异常: 线程“main”java.lang.ClassCas

我把值放到hashmap中,它的形式是

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

List valueToMatch=(List)highLowValueMap.values();
但是,它会引发一个异常:

线程“main”java.lang.ClassCastException中的异常:
无法将java.util.HashMap$值转换为java.util.List

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

List<Double> valuesToMatch  = new ArrayList<Double>( highLowValueMap.values());
List valuesToMatch=new ArrayList(highLowValueMap.values());
TL;博士 深入了解JavaAPI源代码 HashMap#values():检查源代码中的返回类型,并问问自己,
java.util.Collection
是否可以强制转换为
java.util.ArrayList
?没有

public Collection<V> values() {
    Collection<V> vs = values;
    return (vs != null ? vs : (values = new Values()));
}
公共集合值(){
集合vs=值;
返回(vs!=null?vs:(value=newvalues());
}
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);
}

公共ArrayList(Collection)这是因为您的值实际上是一个HashSet。 您可以编写如下代码来迭代集合:

List<Double> valuesToMatch=new ArrayList<>();
for(Double d : highLowValueMap.values(){
  valuesToMatch.put(d);
}
List valueToMatch=new ArrayList();
for(双d:highLowValueMap.values(){
值。放置(d);
}

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

e、 g


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

可以通过阅读JavaDoc找到答案

values()
方法返回一个
集合

所以

List valueToMatch=(List)highLowValueMap.values();
应该是

Collection<Double> valuesToMatch= highLowValueMap.values();
Collection valueToMatch=highLowValueMap.values();
您仍然可以像遍历列表一样遍历此集合


这项工作:

List<Double> valuesToMatch  = new ArrayList<Double>( highLowValueMap.values() );
List valuesToMatch=new ArrayList(highLowValueMap.values());
因为
ArrayList
有一个接受集合的构造函数。

这是因为
values()
返回
collection
,根据
HashMap
的源代码,它属于
AbstractCollection
类型,因此不能强制转换到
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
传递它的
values()
结果,因为
ArrayList
构造函数可以将
Collection
作为其参数。

是否检查了API、方法返回了什么?以及ArrayList接受了什么?

values
HashMap
类中的内部类(请参见
java.util.HashMap$Values
中的$symbol)。
HashMap.values()方法将返回未实现
List
接口的
values
类的对象。
ClassCastException

这是HashMap中的
内部私有类,它没有实现
列表
接口。甚至AbstractCollection也没有实现
列表
接口。
AbstractCollection
实现了
Collection
接口。因此无法强制转换到
列表

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();
        }
    }
但以下说法是不正确的

HashMap<String, String> map  = new HashMap<String, String>();
List c = map.values(); //compilation error.. return type is not List
HashMap map=newhashmap();
List c=map.values();//编译错误..返回类型不是List

我也面临同样的问题,但后来我意识到values()返回集合,而不是列表。 但我们可以实例化一个新的ArrayList,如下所示:

List ValueToMatch=new ArrayList(highLowValueMap.values())


因为ArrayList有一个构造函数,可以将Collection作为其参数。

我怀疑所选的最佳答案,它说: “因为HashMap#values()返回java.util.Collection,而您不能将集合强制转换为ArrayList,因此您会得到ClassCastException。”


这并不是因为集合不能强制转换到ArrayList,真正的原因是HashMap.values()返回的集合由内部类HashMap.values.和HashMap.values备份,而不是ArrayList的超类。

要将值从映射实例转换为列表,可以使用
Iterable.Map

val yourList: List<Any> = #Map.values.map { it }
val-yourList:List=#Map.values.Map{it}

values方法返回一个集合,而不是列表。不,
values()
方法返回一个
collection
keySet()
返回一个
集合
。您可以通过add而不是put将项目添加到ArrayList,这是Set。您的答案是最容易理解的。我不明白为什么我可以执行
集合c=new ArrayList();
但不能强制转换
值()
到该类型,甚至
列表
@ashur这是因为这种方式可以将代码转换为接口,这是可以接受的。在您的示例中,您可以将集合更改为列表(因为它也是一个接口),但仍然可以,但不能转换为接口。
Collection<Double> valuesToMatch= highLowValueMap.values();
List<Double> valuesToMatch  = new ArrayList<Double>( highLowValueMap.values() );
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();
        }
    }
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);
    }
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
val yourList: List<Any> = #Map.values.map { it }