の違いは何ですか?
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
2.List<Integer> list2 = Arrays.asList(ia);
ここで ia
は整数の配列である。
list2`ではいくつかの操作ができないことを知りました。なぜでしょうか? メモリにはどのように格納されているのでしょうか (参照 / コピー)?
リストをシャッフルすると、list1
は元の配列に影響を与えませんが、list2
は影響を与えます。それにしてもlist2
はなんだか混乱しますね。
リストにアップキャストされるArrayList
は、新しいArrayList
を作るのとどう違うのでしょうか?
list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
1.まず、これで何ができるのか見てみましょう。
Arrays.asList(ia)
配列 `ia` を受け取り、`List<Integer>` を実装したラッパーを作成し、元の配列をリストとして利用できるようにしています。何もコピーされず,1つのラッパーオブジェクトが作成されるだけです.リストラッパーに対する操作は,元の配列に伝播します.つまり,リストラッパーをシャッフルすると,元の配列もシャッフルされ,要素を上書きすると,元の配列でも上書きされる,といった具合です.もちろん,リストの要素を追加したり削除したりといった,一部の `List` 操作はラッパーではできません。
リストのラッパーは、`ArrayList`を拡張していないことに注意してください - 別の種類のオブジェクトです。List wrapperは`ArrayList`を拡張していないことに注意してください。これは別の種類のオブジェクトです。`ArrayList`は独自の内部配列を持ち,そこに要素を格納し,内部配列のサイズを変更することができます。ラッパーは独自の内部配列を持たず、与えられた配列に対してのみ操作を伝達します。
2.一方で,その後,新しい配列を
new ArrayList<Integer>(Arrays.asList(ia))
として新しい配列を作成すると、元の配列の完全で独立したコピーである、新しい`ArrayList`が作成されます。ここでは、`Arrays.asList`を使用してラッパーを作成していますが、これは新しい`ArrayList`の構築時にのみ使用され、その後はごみとして回収されます。この新しい `ArrayList` の構造は、元の配列とは完全に独立しています。同じ要素を含みますが(元の配列とこの新しい`ArrayList`の両方が、メモリ上の同じ整数を参照します)、参照を保持する新しい内部配列を作成します。そのため、配列をシャッフルしたり、要素を追加・削除したりしても、元の配列は変更されません。
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
この場合、list1
はArrayList
という型になります。
List<Integer> list2 = Arrays.asList(ia);
ここでは、リストは List
ビューとして返されます。つまり、そのインターフェイスに付属するメソッドのみを持っています。したがって、いくつかのメソッドは list2
では使用できません。
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
ここでは、新しい ArrayList
を作成しています。コンストラクタで値を渡しているだけです。これはキャストの例ではありません。キャスティングの場合は、次のようになります。
ArrayList list1 = (ArrayList)Arrays.asList(ia);