ListChangeListener - 正确的变更顺序

ListChangeListener - correct change order

正确的变更顺序是什么?

在此处的文档中 - click,我们可以看到以下示例:

 ObservableList<Item> theList = ...;

 theList.addListener(new ListChangeListener<Item>() {
     public void onChanged(Change<Item> c) {
         while (c.next()) {
             if (c.wasPermutated()) {
                 for (int i = c.getFrom(); i < c.getTo(); ++i) {
                      //permutate
                 }
             } else if (c.wasUpdated()) {
                      //update item
             } else {
                 for (Item remitem : c.getRemoved()) {
                     remitem.remove(Outer.this);
                 }
                 for (Item additem : c.getAddedSubList()) {
                     additem.add(Outer.this);
                 }
             }
         }
     });

 }

但是示例代码下面有:

Note: in case the change contains multiple changes of different type, these changes must be in the following order: permutation change(s), add or remove changes, update changes. This is because permutation changes cannot go after add/remove changes as they would change the position of added elements. And on the other hand, update changes must go after add/remove changes because they refer with their indexes to the current state of the list, which means with all add/remove changes applied.

这个例子是不是错了?或者我可能遗漏了什么?

ObservableList 可以触发三种类型的更改:

  1. 排列(顺序改变)
  2. Addition/removal(或者替换,也就是同步增删)
  3. 更新(元素 属性 的更改,需要 an "extractor"

一个变化可以只是这些类型中的一种。但是,单个 Change 实例 可以承载多个 更改 。这就是为什么您必须通过在 while 循环中调用 next() 来迭代 Change 实例。

您引用的文档:

Note: in case the change contains multiple changes of different type, these changes must be in the following order: permutation change(s), add or remove changes, update changes.

与上述 next() 方法返回的更改顺序有关。这里的顺序很重要,因为 Change 必须报告列表 当前存在 .

该文档不规定您查询更改类型的顺序。如果更改不是排列,则 c.wasPermutated() 只是 returns false 并且代码继续。与其他类型的更改相同。请注意,由于 API 的设计方式,如果更改既不是排列也不是更新,那么它 必须是 添加或删除(或替换)。

所以这个例子没有错。如果你愿意,你可以把它写成:

while (c.next()) {
  if (c.wasPermutated()) {
    // process perumutation
  } else if (c.wasRemoved() || c.wasAdded()) {
    // process removal, addition, or replacement
  } else {
    // process update
  }
}

但这不会改变代码的行为。