我正在尝试将两个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));

10-02 23:13