请考虑Lecturer.java
中的以下代码。 Lecture.java
中的setter具有完全相同的形式。另请注意,感兴趣的属性为private
。
public void setLecture(Lecture lecture) {
if (this.lecture == lecture) return;
if (this.lecture != null) {
this.lecture.setLecturer(null);
}
this.lecture = lecture;
if (this.lecture != null) {
this.lecture.setLecturer(this);
}
}
尝试设置之前未null
的{{1}}值时,会产生无限循环。
我无法相信这很难保持1:1的关系一致 - 但我无法弄清楚如何做到这一点。如何解决这个问题?
答案 0 :(得分:0)
最后,这是您的解决方案:
public class A {
private B b;
public void setB(B b) {
if(this.b != null) {
this.b.unsetA();
}
this.b = b;
if(b != null && b.getA() != this) {
this.b.setA(this);
}
}
public void unsetB() {
this.b = null;
}
public B getB() {
return b;
}
}
public class B {
private A a;
public void setA(A a) {
if(this.a != null) {
this.a.unsetB();
}
this.a = a;
if(a != null && a.getB() != this) {
this.a.setB(this);
}
}
public void unsetA() {
this.a = null;
}
public A getA() {
return a;
}
}
我的测试班:
public class Test {
public static void main(String ... args) {
A a1 = new A();
B b1 = new B();
A a2 = new A();
B b2 = new B();
checkForZeroOrTwoRelations(a1, a2, b1, b2);
a1.setB(b1);
checkForZeroOrTwoRelations(a1, a2, b1, b2);
b1.setA(a2);
checkForZeroOrTwoRelations(a1, a2, b1, b2);
b2.setA(a2);
checkForZeroOrTwoRelations(a1, a2, b1, b2);
b2.setA(null);
checkForZeroOrTwoRelations(a1, a2, b1, b2);
}
private static void checkForZeroOrTwoRelations(A a1, A a2, B b1, B b2) {
int i = 0;
if(a1.getB() != null) i++;
if(a2.getB() != null) i++;
if(b1.getA() != null) i++;
if(b2.getA() != null) i++;
if(i != 0 && i != 2) {
throw new IllegalStateException();
}
}
}
答案 1 :(得分:0)
您只需将object属性设置为 null 即可打破无限循环。但首先必须将先前的值存储到临时变量中。它会在第一个if
语句处停止,其中null
等于null
。
public void setLecture(Lecture lecture) {
if (this.lecture == lecture) {
return;
}
if (this.lecture != null) {
Lecture pastLecture = this.lecture;
this.lecture = null;
pastLecture.setLecturer(null);
pastLecture = null;
}
this.lecture = lecture;
if (lecture != null) {
lecture.setLecturer(this);
}
}
答案 2 :(得分:0)
我将其作为一个不同的答案发布,实际上我认为,我的第一个答案是你正在寻找的。 em>
至于我的建议,您可以创建一个双向地图(或者您可以使用Guava HashBiMap)来确保关系完整性。
Map<Lecturer, Lecture> lecturerMap = new HashMap();
Map<Lecture, Lecturer> lectureMap = new HashMap();
public void addRelation(Lecturer lecturer, Lecture lecture) {
this.checkIntegrity(lecturerMap,lectureMap, lecturer, lecture);
this.checkIntegrity(lectureMap, lecturerMap, lecture, lecturer);
lecturerMap.put(lecturer, lecture);
lectureMap.put(lecture, lecturer);
}
private <T,V> void checkIntegrity(Map<T,V> mapf, Map<V,T> maps, T t, V v) {
if (mapf.containsKey(t)) {
V value = mapf.get(t);
if (maps.containsKey(value)) {
maps.remove(value);
}
mapf.remove(t);
}
}
肯定有更复杂的方法可以做,但这项工作也是如此。