繁体   English   中英

uniqueUntilChanged无法正常工作(例如,不同的列表大小不视为不同)

[英]distinctUntilChanged not working (e.g. different list size is not considered different)

我的观察结果如下:

obs
    .doOnNext { logger("Items changed (${it.size})") }
    .distinctUntilChanged()
    .doOnNext { logger("Items changed (${it.size})- EMIITTED") }

日志如下:

Items changed (7)
Items changed (7)- EMIITTED
Items changed (8)
// => missing EMIITTED message although it.size has changed => WHY?

此处将默认比较器与可比较项的列表一起使用似乎失败了。 为什么? 如果观察到的发射列表项的大小已更改,则数据将不同,因此distinctUntilChanged不应筛选出新列表。 但似乎这里发生了这种情况。 为什么?

我真的需要提供我自己的比较distinctUntilChanged如果我发射出比较列表大小和项目一个接一个的项目列表?

编辑

我的obs基本上如下所示:

obs = Observable.combineLatest(
    RxDBDataManager.appsManager.observeList(),
    RxDBDataManager.widgetsManager.observeList(),
    RxDBDataManager.shortcutsManager.observeList(),
    RxDBDataManager.customItemsManager.observeList(),
    RxDBDataManager.foldersManager.observeList(),
    Function5<List<IDBApp>, List<IDBWidget>, List<IDBShortcut>, List<IDBCustomItem>, List<IDBFolder>, List<IFolderOrSidebarItem>> { t1, t2, t3, t4, t5 ->
        val list = ArrayList<IFolderOrSidebarItem>()
        list.addAll(t1)
        list.addAll(t2)
        list.addAll(t3)
        list.addAll(t4)
        list.addAll(t5)
        list
    }
    .flatMapSingle {
        Observable.fromIterable(it)
                .filter { it.parentType == parentType && it.parentId == parentId }
                .cast(T::class.java)
                .toList()
    }
    .flatMapSingle {
        Observable.fromIterable(it)
                .sorted(comparator)
                .toList()
    }

另外,我对这些数据进行了一些排序和过滤

根据交流中的评论:

鼓励RxJava用户在其流中使用不可变数据类型,以防止发生并发问题,例如在不同阶段从不同线程修改同一对象,从而导致操作员行为中断和看似不可能的业务逻辑故障。

在这种情况下, distinctUntilChanged不能按预期方式工作,因为可变项的更改方式是,随后的两个onNext信号基本上具有相同的内容,并且运算符将它们滤除为不明显。

检测所涉及的项目是否实际上无意中相同的一种方法是使用运算符的双谓词版本,然后在自定义lambda中放置一个断点。 这样一来,您可以检查先前的值和当前的值,并查看它们是否真正相等,即使它们不应该相等:

source.distinctUntilChanged((prev, curr) -> {
    // breakpoint the next line
    return prev.equals(curr);
});

在这种情况下,行为中断是由于可变项在某处发生了更改,因此其评估结果与当前/先前相同。 使用List ,断点所有突变方法(例如addaddAllsetremove等) addAll ,但是可以将可变列表变成不可变列表并沿序列发送。 内置方法是通过Collections::unmodifiableList对其进行转换:

  source
  .toList()
  .map(Collections::unmodifiableList)
  ;

每当在现在无法修改的列表实例上尝试进行突变时,这都会崩溃,并指出应进一步研究的逻辑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM