我正在尝试将两个ListProperties
双向绑定。问题是,它们具有不同的类型(A和B)。Test4#test01()
说明了我想做什么。Test4#test02()
是我的幼稚方法,但这导致StackOverflowError
如何使用给定的AB变压器和BA变压器将List<A>
双向绑定到List<B>
?
这是MWE:
public class Test4 {
public Test4() {
}
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
class A {
@Override
public boolean equals(final Object obj) {
return obj instanceof A;
}
}
class B {
@Override
public boolean equals(final Object obj) {
return obj instanceof B;
}
}
ListProperty<A> listA = new SimpleListProperty<>(FXCollections.observableArrayList());
ListProperty<B> listB = new SimpleListProperty<>(FXCollections.observableArrayList());
Function<A, B> trivialTransformerAB = a -> new B();
Function<B, A> trivialTransformerBA = b -> new A();
ListChangeListener<A> listAListener;
ListChangeListener<B> listBListener;
@Test
public void test01() {
// Bindings.bindContentBidirectional(listA, listB,
// trivialTransformerAB, trivialTransformerBA);
}
@Test
public void test02() {
listAListener = c -> {
while (c.next()) {
if (c.wasRemoved() || c.wasUpdated()) {
c.getList().subList(c.getFrom(), c.getTo())
.forEach(a -> listB.remove(trivialTransformerAB.apply(a)));
}
if (c.wasAdded() || c.wasUpdated()) {
c.getList().subList(c.getFrom(), c.getTo()).forEach(a -> {
final B b = trivialTransformerAB.apply(a);
if (!listB.contains(b)) {
listB.add(trivialTransformerAB.apply(a));
}
});
}
}
};
listBListener = c -> {
while (c.next()) {
if (c.wasRemoved() || c.wasUpdated()) {
c.getList().subList(c.getFrom(), c.getTo())
.forEach(b -> listA.remove(trivialTransformerBA.apply(b)));
}
if (c.wasAdded() || c.wasUpdated()) {
c.getList().subList(c.getFrom(), c.getTo()).forEach(b -> {
final A a = trivialTransformerBA.apply(b);
if (!listA.contains(a)) {
listA.add(trivialTransformerBA.apply(b));
}
});
}
}
};
listA.addListener(listAListener);
listB.addListener(listBListener);
listA.add(new A());
assertThat(listB.size(), is(1));
}
}
错误:
java.lang.StackOverflowError
at java.util.Collections$UnmodifiableCollection.isEmpty(Collections.java:1031)
at java.util.Collections$UnmodifiableCollection.isEmpty(Collections.java:1031)
[..]
最佳答案
设置侦听器的方式创建了一个无限循环。
我建议在这两行中分别设置一个断点,并逐步使用调试器:
listB.add(trivialTransformerAB.apply(a));
listA.add(trivialTransformerBA.apply(b));