大赞。
你的考虑是对的。但是,在Java中,无法通过访问限制的问题解决(C++中可以解决)。你的clone的方法是ok的,但是增大了开销。
事实上,Java标准库中的数据结构,有同样的问题。以PriorityQueue为例(底层就是堆),你可以实验如下代码:// 创建一个学生类
public class Student implements Comparable{
public String name;
public int score;
public Student(String name, int score){
this.name = name;
this.score = score;
}
// 学生类可以按照分数做比较
@Override
public int compareTo(Student another){
return another.score - score;
}
@Override
public String toString(){
return this.name + " " + String.valueOf(this.score);
}
}
然后,实验如下Main:import java.util.PriorityQueue;
public class Main {
public static void main(String[] args) {
PriorityQueue pq = new PriorityQueue<>();
pq.add(new Student("A", 60));
pq.add(new Student("B", 100));
pq.add(new Student("C", 80));
// 打印优先队列的第一名,应该是B同学,100分嘛
System.out.println(pq.peek());
// 现在,把第一名取出来
Student topStudent = pq.peek();
// 他的成绩判错了,其实是15分,直接修改
topStudent.score = 15;
// 再打印优先队列的第一名,还是B同学。可却是15分
System.out.println(pq.peek());
}
}
所以,这个问题在Java语言中是一个设计困境。看你的取舍了。当前的设计,就是需要调用者保证不直接修改优先队列中的引用内容。这就好比用户调用数组元素,需要保障数组索引不越界;调用出栈或者出队操作,需要保障栈或者队不为空一样:)
继续加油!:)