gpt4 book ai didi

java - InvalidationListener 与 ChangeListener

转载 作者:太空宇宙 更新时间:2023-11-04 10:13:07 27 4
gpt4 key购买 nike

我有一个用例,我想将多个 ObservableValue 绑定(bind)到一个 Observable 上,因为我实际上对值变化是什么不感兴趣,我只需要一种在变化时收到通知的方法。

这就是 Observable 绑定(bind),我想到了:

BooleanBinding() {
{
super.bind(proxy.activeShipProperty());
INavigableVessel activeShip = proxy.getActiveShip();
super.bind(activeShip.getLoadBinding());
if (activeShip instanceof IShip) {
super.bind(((IShip) activeShip).travelState());
} else {
super.bind(((IConvoy) activeShip).getOrlegShip().travelState());
}
super.bind(date.dayDateBinding());
}
private boolean value = true;
@Override
protected boolean computeValue() {
value = !value;
return value;
}
};

然后是这个测试代码,以验证它是否按预期工作:

Observable observable = contentProvider.createObservable(ENoticeBoardType.SHIP_WARE_INFO, proxy);
IntegerProperty invalidationCounter = new SimpleIntegerProperty(0);

InvalidationListener listener = observable1 -> invalidationCounter.setValue(invalidationCounter.get() + 1);
observable.addListener(listener);

// When
dayBinding.invalidate();
loadBinding.invalidate();
travelState.set(EShipTravelState.ANCHOR);
activeVessel.set(mock(IShip.class));

// Then
assertEquals(4, invalidationCounter.get());

事实证明并非如此。 invalidationCounter 仅在第一次无效调用时增加一次。

但是,当我将上面的 BooleanBinding 处理为 ObservableValue 时,我可以添加一个 ChangeListener:

ChangeListener listener = (obs, oldValue, newValue) -> invalidationCounter.setValue(invalidationCounter.get() + 1);
observable.addListener(listener);

// When
dayBinding.invalidate();
loadBinding.invalidate();
travelState.set(EShipTravelState.ANCHOR);
activeVessel.set(mock(IShip.class));

// Then
assertEquals(4, invalidationCounter.get());

这按预期工作。

我想知道/已经确认的是: InvalidationListener 仅被调用一次,当 Observable 变得无效时,它不会变回有效,以便它再次有效。然而,使用 ChangeListener 会强制计算新值,因此 ObservableValue 再次变得有效。

根据这一观察,是否有任何用例我实际上可以使用 Observable

最佳答案

Observable 只是一个接口(interface),实现决定调用 invalidate 是否会触发处于某种状态的监听器。您在此处观察到的行为是 BooleanBinding 仅触发一次 invalidation 更新,直到使用 get() 方法检索该值为止。
一旦通知监听者,观察者就应该知道该值可能已经改变。

这是为了避免不必要的计算而进行的优化。例如。考虑以下场景:存在三个 BooleanProperty b1b2b3,并且您对 b1 && (b2 || b3) 感兴趣。在这种情况下,您可以应用短路评估,如果 b1false,则不需要评估 (b2 || b3);如果 b2true,则评估 (b2 || b3) 不需要您评估 b3。如果 b2 和/或 b3 的计算成本很高,那么如果您可以避免的话,不评估它们会使代码性能更高,例如使用以下实现

BooleanBinding binding = new BooleanBinding() {
{
bind(b1, b2, b3);
}

@Override
protected boolean computeValue() {
if (!b1.get()) {
return false;
}
if (b2.get()) {
return true;
} else {
return b3.get();
}

// the above is basically a longer version of

// return b1.get() && (b2.get() || b3.get());

// to highlight the short circuiting behaviour
}
};

ChangeListenerInvalidationListener 不同,需要将新值传递给它们,因此添加任何 ChangeListener 都会导致调用 get(),并且每个 invalidation 调用都会触发对 computeValue 的调用。

关于java - InvalidationListener 与 ChangeListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52075244/

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