gpt4 book ai didi

java - 创建不可变类时,集合是否应该只包含不可变对象(immutable对象)?

转载 作者:塔克拉玛干 更新时间:2023-11-01 23:07:15 26 4
gpt4 key购买 nike

目前正在备考...在过去的一篇论文中遇到了这个问题。

Consider the following Student and Tutor classes:

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;
}
}

导师:

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]);
}
}

public Set<Student> getTutees() {
return Collections.unmodifiableSet(tutees);
}

public String getName() {
return name;
}
}

Re-write the Tutor class to make it immutable(without modifying the Student class).

我知道name字段应该有final修饰符来保证线程安全。

如果学生 Set 包含可变的 Student 对象,并且 Student 类不能更改,那么我们如何使该类不可变?也许创建 Set 的克隆并在每次调用 getTutees 方法时清除 tutees 并将克隆的元素添加到其中?

或者尽管集合包含可变对象,它是否已经不可变?

最佳答案

集合的成员也需要是不可变的。不可修改仅意味着不能添加或删除任何元素。

即使集合是不可修改的,一旦访问它的代码引用了属于该集合的元素,那么如果该元素不是不可变的,那么它就可以被更改。

如果集合的 getter 返回一个防御副本,创建一个新的 Set 引用新的 Student 对象并返回它而不是原始集合,那么这将使集合不可变。

public Set<Student> getTutees() {
Set newSet = new HashSet();
for (Student tutee : tutees) {
newSet.add(new Student(tutee.getName(), tutee.getCourse()));
}
return newSet;
}

在此处添加一个示例以表明使用 Collections.unmodifiableSet 是不够的:

import java.util.*;

public class ImmutabilityExample {
public static void main(String[] args) {
Student student = new Student("Joe", "Underwater Basketweaving 101");
Tutor tutor = new Tutor("Bill", new Student[] {student});
Set<Student> students = tutor.getTutees();
System.out.println("before=" + students);
students.iterator().next().setName("Mary");
System.out.println("" + tutor.getTutees());
}
}

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;
}
public String toString() {
return "Student, name=" + name + ", course=" + course;
}
}

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]);
}
}

public Set<Student> getTutees() {
return Collections.unmodifiableSet(tutees);
}

public String getName() {
return name;
}
}

这个的输出是:

before=[Student, name=Joe, course=Underwater Basketweaving 101]
[Student, name=Mary, course=Underwater Basketweaving 101]

关于java - 创建不可变类时,集合是否应该只包含不可变对象(immutable对象)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37446594/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com