在Flux反应器中过滤重复的对象

时间:2019-01-26 21:54:36

标签: spring spring-webflux project-reactor

如何过滤自己班级的重​​复对象?例如: 我有一个具有以下属性的类:

public class MyClass{
  private String id;
  private Date lastUpdate;
  //Getter and Setter are available
}

现在我有一个包含许多MyClass对象的助焊剂。它们可以包含相同的ID,但具有不同的日期。我想删除所有具有相同ID的对象,但我想保留最后更新的对象。

Flux<MyClass> fluxMyContainer = Flux.just(new MyClass("1", "2017-01-02), 
  new MyClass("2", "2018-11-05"), new MyClass("1", "2018-05-04"));

在这种情况下,我想删除第一个元素。 有没有人知道如何做到这一点而不会受到阻碍?

3 个答案:

答案 0 :(得分:2)

嗨,如果您只想过滤重复项,请使用 .distinc(), https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html#distinct-

  `Flux.just(
    new MyClass("1", LocalDate.of(1990, 2, 3)),
    new MyClass("1", LocalDate.of(2000, 3, 1)),
    new MyClass("2", LocalDate.of(1000, 2, 2)),
    new MyClass("2", LocalDate.of(2010, 4, 5)),
    new MyClass("2", LocalDate.MIN),
    new MyClass("3", LocalDate.MIN))
   .distinct(MyClass::getId)
   .subscribe(System.out::println);`

结果可以。

   `MyClass{id='1', lastUpdate=2000-03-01}
    MyClass{id='2', lastUpdate=2010-04-05}
    MyClass{id='3', lastUpdate=-999999999-01-01}`

答案 1 :(得分:0)

我想到的一个解决方案是:

  1. groupBy id
  2. 然后reduce个小组提交较早的参赛作品
  3. 最终flatMap Mono s

代码:

Flux.just(...)
    .groupBy(MyClass::getId)
    .flatMap(g -> g.reduce((a, b) -> a.getLastUpdate().compareTo(b.getLastUpdate()) > 0 ? a : b))
    .subscribe(System.out::println);

例如:

Flux.just(
    new MyClass("1", LocalDate.of(1990, 2, 3)),
    new MyClass("1", LocalDate.of(2000, 3, 1)),
    new MyClass("2", LocalDate.of(1000, 2, 2)),
    new MyClass("2", LocalDate.of(2010, 4, 5)),
    new MyClass("2", LocalDate.MIN),
    new MyClass("3", LocalDate.MIN))
    .groupBy(MyClass::getId)
    .flatMap(g -> g.reduce((a, b) -> a.getLastUpdate().compareTo(b.getLastUpdate()) > 0 ? a : b))
    .subscribe(System.out::println);

将打印:

MyClass{id='1', lastUpdate=2000-03-01}
MyClass{id='2', lastUpdate=2010-04-05}
MyClass{id='3', lastUpdate=-999999999-01-01}

答案 2 :(得分:0)

删除反应堆中的重复项将阻塞整个管道,无论您使用哪种解决方案,都没有不可阻塞的方式

因为删除重复的逻辑本身需要在发出结果之前遍历所有项目。 其他需要首先遍历所有项目的逻辑(如排序通量)也将阻塞管道,如果要归档非阻塞管道,请谨慎使用此类逻辑。

不知道为什么会遇到这种情况,如果您坚持a)不需要重复并且b)无阻塞,则更改设计。

例如,过滤后的结果(唯一的)需要在用户界面中显示, 那么您可以首先在用户界面中一次显示原始数据。如果来自助焊剂的新发射项目重复,则只需更新UI中已显示的项目即可。