Java で汎用リストのクローンを作成するにはどうすればよいですか?
質問
を持っています ArrayList<String>
のコピーを返却したいのですが。 ArrayList
次のシグネチャを持つ clone メソッドがあります。
public Object clone()
このメソッドを呼び出した後、返されたオブジェクトをキャストして戻すにはどうすればよいですか? ArrayList<String>
?
解決
ArrayList newArrayList = (ArrayList) oldArrayList.clone();
他のヒント
なぜクローンを作成したいのですか?通常は、新しいリストを作成する方が合理的です。
List<String> strs;
...
List<String> newStrs = new ArrayList<>(strs);
仕事は終わりました。
これは私がそのために使用するコードです:
ArrayList copy = new ArrayList (original.size());
Collections.copy(copy, original);
希望はあなたにとって役に立ちます
Java 8 では、ストリームを使用してクローンを作成できます。
import static java.util.stream.Collectors.toList;
...
List<AnObject> clone = myList.stream().collect(toList());
Object.clone() にはいくつかの重大な問題があるため、ほとんどの場合、その使用は推奨されないことに注意してください。項目 11 を参照してください。効果的なJava完全な回答については、Joshua Bloch による。プリミティブ型配列で Object.clone() を安全に使用できると思いますが、それとは別に、clone の適切な使用とオーバーライドについては慎重に行う必要があります。おそらく、セマンティクスに従って明示的にオブジェクトのクローンを作成するコピー コンストラクターまたは静的ファクトリ メソッドを定義する方がよいでしょう。
Collections API を使用すると、これでうまくいくはずだと思います。
注記:copy メソッドは線形時間で実行されます。
//assume oldList exists and has data in it.
List<String> newList = new ArrayList<String>();
Collections.copy(newList, oldList);
addAll を使用するとうまく機能することがわかりました。
ArrayList<String> copy = new ArrayList<String>();
copy.addAll(original);
ジェネリック構文ではなく括弧が使用されます
ゲッターでリストを返せるようにするためにこれが必要な場合は、次のようにすることをお勧めします。
ImmutableList.copyOf(list);
次のような汎用インターフェイスのクローンを作成するには、 java.util.List
それをキャストするだけです。ここに例があります:
List list = new ArrayList();
List list2 = ((List) ( (ArrayList) list).clone());
これは少し難しいですが、返されるものに制限がある場合は機能します。 List
インターフェースを備えているので、後から誰でも好きなときにリストを実装できます。
この答えが最終的な答えに近いことはわかっていますが、私の答えは、作業中にそれらすべてを行う方法についての答えです。 List
-一般的な親-ではありません ArrayList
ArrayList を複製するときは十分に注意してください。Java でのクローン作成は浅いものです。これは、Arraylist 自体のクローンのみが作成され、そのメンバーのクローンは作成されないことを意味します。したがって、ArrayList X1 があり、それを X2 にクローンすると、X2 の変更は X1 にも反映され、その逆も同様です。クローンを作成すると、元の要素と同じ要素へのポインターを含む新しい ArrayList が生成されるだけです。
これも機能するはずです:
ArrayList<String> orig = new ArrayList<String>();
ArrayList<String> copy = (ArrayList<String>) orig.clone()
ArrayList first = new ArrayList ();
ArrayList copy = (ArrayList) first.clone ();
私は Java の専門家ではありませんが、同じ問題があり、この方法で解決しようとしました。(T にはコピー コンストラクターがあると仮定します)。
public static <T extends Object> List<T> clone(List<T> list) {
try {
List<T> c = list.getClass().newInstance();
for(T t: list) {
T copy = (T) t.getClass().getDeclaredConstructor(t.getclass()).newInstance(t);
c.add(copy);
}
return c;
} catch(Exception e) {
throw new RuntimeException("List cloning unsupported",e);
}
}
List<String> shallowClonedList = new ArrayList<>(listOfStrings);
これは単なる浅いコピーであり、深いコピーではないことに注意してください。新しいリストが得られますが、エントリは同じです。単なる文字列の場合は問題ありません。リストのエントリ自体がオブジェクトである場合、Get はさらに複雑になります。