1. ホーム
  2. java

[解決済み] HashMapの値がListにキャストされないのはなぜですか?

2023-06-05 14:25:57

質問

ハッシュマップに値を入れているのですが、それは以下のような形式です。

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$Values を java.util.List にキャストすることができません。

でも、リストの作成に渡すことができるんです。

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

どのように解決するのですか?

TL;DR

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

説明

なぜなら HashMap#values()java.util.Collection<V> をキャストすることはできません。 CollectionArrayList に変換すると、以下のようになります。 ClassCastException .

を使うことをお勧めします。 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);
}