Java LinkedList clone() メソッド
clone()メソッドは Java のObjectクラスのメソッドで、現在のオブジェクトのコピーを作成して返すために使用されます。LinkedListLinkedList クラスでは、このメソッドはリンクリストの浅いコピーを実装するためにオーバーライドされています。
重要なポイント:
- 返されるのは新しい
LinkedListオブジェクト - 新しいリンクリストには元のリンクリストと同じ要素が含まれます
- 要素自体はコピーされません(浅いコピー)
メソッド構文
public Object clone()
戻り値:
- この LinkedList
LinkedListの浅いコピーを返します
例外:
- 例外はスローされません
clone() メソッドの使い方
基本的な使用例
例
import java.util.LinkedList;
public class LinkedListCloneExample {
public static void main(String[] args) {
// 元のリンクリストを作成
LinkedList<String> originalList = new LinkedList<>();
originalList.add("Apple");
originalList.add("Banana");
originalList.add("Cherry");
// リンクリストをクローン
LinkedList<String> clonedList = (LinkedList<String>) originalList.clone();
// 2つのリンクリストを出力
System.out.println("Original List: " + originalList);
System.out.println("Cloned List: " + clonedList);
}
}
public class LinkedListCloneExample {
public static void main(String[] args) {
// 元のリンクリストを作成
LinkedList<String> originalList = new LinkedList<>();
originalList.add("Apple");
originalList.add("Banana");
originalList.add("Cherry");
// リンクリストをクローン
LinkedList<String> clonedList = (LinkedList<String>) originalList.clone();
// 2つのリンクリストを出力
System.out.println("Original List: " + originalList);
System.out.println("Cloned List: " + clonedList);
}
}
出力結果:
Original List: [Apple, Banana, Cherry] Cloned List: [Apple, Banana, Cherry]
浅いコピー vs 深いコピー
浅いコピーの特徴
- 要素の参照が同じ:クローン後のリンクリストと元のリンクリストの要素は同じオブジェクトです
- 要素の変更は両方に影響します:リンクリスト内のオブジェクトを変更すると、両方のリンクリストに影響します
例
import java.util.LinkedList;
class Fruit {
String name;
Fruit(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public class ShallowCopyExample {
public static void main(String[] args) {
LinkedList<Fruit> original = new LinkedList<>();
original.add(new Fruit("Apple"));
LinkedList<Fruit> cloned = (LinkedList<Fruit>) original.clone();
// 元のリンクリストの要素を変更
original.get(0).name = "Orange";
System.out.println("Original: " + original);
System.out.println("Cloned: " + cloned);
}
}
class Fruit {
String name;
Fruit(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public class ShallowCopyExample {
public static void main(String[] args) {
LinkedList<Fruit> original = new LinkedList<>();
original.add(new Fruit("Apple"));
LinkedList<Fruit> cloned = (LinkedList<Fruit>) original.clone();
// 元のリンクリストの要素を変更
original.get(0).name = "Orange";
System.out.println("Original: " + original);
System.out.println("Cloned: " + cloned);
}
}
出力結果:
Original: [Orange] Cloned: [Orange]
深いコピーを実装する方法
完全に独立したコピー(要素を含む)が必要な場合は、手動で深いコピーを実装する必要があります:
例
import java.util.LinkedList;
class Fruit implements Cloneable {
String name;
Fruit(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return name;
}
}
public class DeepCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
LinkedList<Fruit> original = new LinkedList<>();
original.add(new Fruit("Apple"));
LinkedList<Fruit> deepCloned = new LinkedList<>();
for (Fruit fruit : original) {
deepCloned.add((Fruit) fruit.clone());
}
// 元のリンクリストの要素を変更
original.get(0).name = "Orange";
System.out.println("Original: " + original);
System.out.println("Deep Cloned: " + deepCloned);
}
}
class Fruit implements Cloneable {
String name;
Fruit(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return name;
}
}
public class DeepCopyExample {
public static void main(String[] args) throws CloneNotSupportedException {
LinkedList<Fruit> original = new LinkedList<>();
original.add(new Fruit("Apple"));
LinkedList<Fruit> deepCloned = new LinkedList<>();
for (Fruit fruit : original) {
deepCloned.add((Fruit) fruit.clone());
}
// 元のリンクリストの要素を変更
original.get(0).name = "Orange";
System.out.println("Original: " + original);
System.out.println("Deep Cloned: " + deepCloned);
}
}
出力結果:
Original: [Orange] Deep Cloned: [Apple]
実際の適用シナリオ
- 元のデータを保護:リンクリストを操作する必要があるが、元のデータを変更したくない場合
- 高速コピー:内容が同じリンクリストをすばやく作成する必要がある場合
- マルチスレッド環境:異なるスレッドで同じデータの独立したコピーを使用する
注意事項
- 型変換:clone() は Object 型を返すため、LinkedList へのキャスト(強制型変換)が必要です
- 要素の不変性:不変オブジェクト(Stringなど)の場合、浅いコピーで十分です
- パフォーマンスの考慮事項:大きなリンクリストをクローンするには一定のパフォーマンスオーバーヘッドがかかります
- 並行性の問題:クローン処理中にリンクリストが変更されると、不整合が生じる可能性があります
よくある質問と回答
Q1: clone() メソッドと直接代入の違いは何ですか?
直接代入(例:list2 = list1)は単に同じオブジェクトを指す新しい参照を作成するだけで、clone()新しい独立したオブジェクトを作成します。
Q2: なぜ clone() メソッドは LinkedList ではなく Object を返すのですか?
これは Java のclone()メソッドの標準設計であり、サブクラスがオーバーライドしてより具体的な型を返す必要があります。
Q3: カスタムオブジェクトの LinkedList をクローンするにはどうすればよいですか?
カスタムクラスがCloneableインターフェースを実装し、clone()メソッドをオーバーライドしていることを確認し、その後、深いコピーの例の方法に従って操作します。
まとめ
LinkedListのclone()このメソッドは、リンクリストのコピーをすばやく作成する方法を提供しますが、浅いコピーであることに注意する必要があります。実際のニーズに応じて、浅いコピーを使用するか深いコピーを実装するかを選択してください。特に可変オブジェクトを含むリンクリストを扱う場合は注意が必要です。
Java LinkedList