2017-05-24 17 views
0

にオブジェクトの防衛的コピーを追加します。現在、私はこのコードを持っているHashSetの

public final class Tutor { 
private String name; 
private final Set<Student> tutees; 
public Tutor(String name, Student[] students){ 
    this.name = name; 
    tutees = new HashSet<Student>(); 
    for (int i = 0; i<students.length; i++) 
     tutees.add(students[i]); 
} 

それは/学生の守備のコピーを追加するのではなくなりますように、私は(ちょうど紙の上)に書き換えしようとしています直接のHashSetにそれらを追加し、次のコードは、そうならば疑問に思って:

public final class Tutor { 
private String name; 
private final Set<Student> tutees; 
public Tutor(String name, Student[] students){ 
    this.name = name; 
    tutees = new HashSet<Student>(); 
    for (int i = 0; i<students.length; i++) 
     tutees.add(students[i](students.getName(), students.getCourse()); 
} 

コードを学生のために必要な場合:

public class Student { 
private String name; 
private String course; 
public Student(String name, String course){ 
    this.name = name; 
    this.course = course; 
} 
public String getName() { return name; } 
public String getCourse() { return course; } 
public void setName(String name) { 
    this.name = name; 
} 
public void setCourse(String course){ 
    this.course = course; 
} 
} 

ありがとう

+0

コンパイラを先に使用してください。少なくとも1つのエラーが見つかります。次に、Studentを引数として取る、Studentクラスの生徒をコピーするために必要なものをカプセル化する、Studentのコンストラクタを書くことを検討してください。 –

答えて

2

あなたは正しいことをしていますが、紙に書いているので間違いがあります。あなたがプログラムにそれを書き換えた場合、それは

tutees.add(new Student(students[i].getName(), students[i].getCourse()); 

ノートで交換する必要が

tutees.add(students[i](students.getName(), students.getCourse()); 

、新しいStudentを追加しているが、フィールドがでinitilaizedされているため、このラインの、コンパイルされないでしょう既存のの結果、シャローコピー-のオブジェクトは異なるが、内容はである。ただし、Stringクラスはimmutableです。つまり、文字列を変更する各メソッドは、変更が適用された新しい文字列を作成し、古い文字列はそのまま残ります。たとえオリジナルの生徒とそのコピーがコンテンツを共有していても、文字列の変更はお互いに影響を及ぼさないので、防御コピーのように動作します。ここで

Student original = new Student("name", "course"); 
Student copy = new Student(original.getName(), original.getCourse()); 
// does not change the name of the copy 
String modifiedName = copy.getName().replaceAll("a", "b"); 

は真守備のコピー(ディープコピー)の例である:効率上の理由については

Student deepCopy = new Student(
     new String(original.getName()), 
     new String(original.getCourse()) 
); 

、あなたはただ、immutableあるクラスで作業している知っていれば参照をコピーします。

+0

ありがとうmatoni、これは十分に問題を解決すると思います!私はどこかに '新しい'が必要だと思っていたが、それは私の頭を丸くすることができませんでした:) – pxdr0

1

変更可能な生徒をSetに入れることは悪い考えです。一度セットに入ったら、セットの契約を壊すので、何かを変更したくない。

コピーを作成すると症状は処理されますが、基本的な問題は処理されません。問題は、あなたのStudentクラスが変更可能であることです。 Studentクラスを不変にすると、コピーを心配する必要はなく、エラーが発生しにくくなります。

public class Student { 
    private String name; 
    private String course; 
    public Student(String name, String course){ 
     this.name = name; 
     this.course = course; 
    } 
    public String getName() { return name; } 
    public String getCourse() { return course; } 
} 

生徒が名前を変更した場合 - 頻度はどのくらいですか?あなたのシステムでは、それをまったくモデル化する必要はないかもしれません。あるいはコースを変更するだけで、新しい学生を作成し、古い、間違ったものを削除するだけです。

+0

ありがとうマイケル!私は変更可能な生徒が根本的な問題であることを知っています。現実のシナリオでこの問題に対処することは、もちろん簡単です – pxdr0

関連する問題