如果过滤后的值为空,如何跳过流过滤器?

时间:2019-10-02 11:47:32

标签: java list java-stream

我有一个Java对象列表。在数据库中,一些对象具有字段nextSyncDate,而有些则没有。我想做的是在Java流上过滤器,但是该字段存在并且例如大于今天。因此,简化一下,我想获得nextSyncDate比今天更大的对象,而没有该字段的对象(在get()之后获得NullPointException)。

我已经尝试过类似的操作,但是它却无法如我所愿。

List<MyObjects> objects;
objects.stream()
    .filter(obj -> Objects.nonNull(obj.getNextSyncDate()) && obj.getNextSyncDate().before(new Date()))

另一方面,所有对象都有字段counter。我还要做的是为nextSyncDate大于15的每个对象设置counter(例如,明天)。我试图在.map()之前设置.filter()个对象,但是它也不起作用。

2 个答案:

答案 0 :(得分:2)

创建流时,您不会直接修改其源。您需要收集数据。您的过滤器似乎按预期工作。我个人不建议使用带有副作用的过滤流(将“ counter> 15然后在其他地方设置nextSyncDate”逻辑),但是可以使用诸如{{1} }(peek用于转换,在您的情况下不是必需的,但可以使用):

map

答案 1 :(得分:1)

过滤器也可以包含counter要求:

    final Date TODAY = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
    final int COUNTER_THRESHOLD = 15;
    objects.stream()
            .filter(obj -> Objects.nonNull(obj.getNextSyncDate())
                    && obj.getNextSyncDate().before(TODAY)
                    && obj.getCounter() > COUNTER_THRESHOLD)

过滤器提供的中间流具有需要更新的对象,因此可以应用forEach:

    final Date TODAY = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
    final Date TOMORROW = Date.from(LocalDate.now().plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
    final int COUNTER_THRESHOLD = 15;
    objects.stream()
            .filter(obj -> Objects.nonNull(obj.getNextSyncDate())
                    && obj.getNextSyncDate().before(TODAY)
                    && obj.getCounter() > COUNTER_THRESHOLD)
            .forEach(obj -> obj.setNextSyncDate(TOMORROW));

此外,考虑使用LocalDate而不是不建议使用的日期。