85

次の形式のハッシュマップに値を入れています。

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

values()mapのメソッドを使ってリストを作成したい。

List<Double> valuesToMatch=new ArrayList<>();
valuesToMatch=(List<Double>) highLowValueMap.values();

また

List<Double> valuesToMatch=(List<Double>) highLowValueMap.values();

ただし、例外がスローされます。

スレッド「メイン」の例外 java.lang.ClassCastException:
java.util.HashMap$Values を java.util.List にキャストできません

しかし、それをリストの作成に渡すことができます。

List<Double> valuesToMatch  = new ArrayList<Double>( highLowValueMap.values());
4

10 に答える 10

150

TL;DR

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

説明

HashMap#values()は a を返し、 aを にjava.util.Collection<V>キャストできないため、 が得られます。CollectionArrayListClassCastException

ArrayList(Collection<? extends V>)コンストラクタを使用することをお勧めします。Collection<? extends V>このコンストラクターは、引数として実装するオブジェクトを受け入れます。次のようなClassCastException結果を渡すと取得できません。HashMap.values()

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

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

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);
}
于 2013-03-20T11:45:05.157 に答える
25

答えは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コレクションを受け入れるコンストラクターがあるためです。

于 2013-03-20T11:45:31.627 に答える
5

これは、のソースコードによると型がであり、したがってにキャストできないものをvalues()返すためです。CollectionHashMapAbstractCollectionList

コンストラクターが引数を取ることができるため、結果のArrayList受け渡しをインスタンス化できます。values()ArrayListCollection

于 2013-03-20T11:45:40.997 に答える
4

List サブタイプ (ArrayList、LinkedList など) のインスタンスをすでに作成している場合は、addAll メソッドを使用できます。

例えば、

valuesToMatch.addAll(myCollection)

リストのサブタイプの多くは、コンストラクターでソース コレクションを受け取ることもできます。

于 2013-03-20T11:45:27.447 に答える
2

APIを確認しましたvalues()か?メソッドによって何が返されますか?そして、どのArrayListコンストラクターが受け入れますか?

于 2013-03-20T11:46:04.550 に答える
1

それは、値が実際には HashSet であるためです。次のようなコードを記述して、セットを反復処理できます。

List<Double> valuesToMatch=new ArrayList<>();
for(Double d : highLowValueMap.values(){
  valuesToMatch.put(d);
}
于 2013-03-20T11:45:08.077 に答える
1

Valuesclass の内部クラスですHashMap( の $ 記号を参照java.util.HashMap$Values)。
HashMap.values() メソッドは 、インターフェイスValuesを実装していないクラスのオブジェクトを返しListます。もそうですClassCastException。 これは、インターフェイスを実装していない HashMap
の内部プライベート クラスです。AbstractCollection もインターフェイスを実装していません。インターフェイスを実装します。そのため、 にキャストできません。ValuesListList
AbstractCollectionCollectionList

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 のコンストラクターの 1 つです。

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
于 2013-03-20T11:57:07.733 に答える