[英]How to skip stream filter if filtered value is null?
I have a list of Java objects.我有一个 Java 对象的列表。 In database some of objects has got field nextSyncDate
and some not.在数据库中,有些对象有字段nextSyncDate
而有些则没有。 What I want to do is to put filter on java stream but only if this field exists and is for example greater than today date.我想要做的是在 java stream 上放置过滤器,但前提是该字段存在并且例如大于今天的日期。 So simplify, I want to get objects which nextSyncDate
is greater than today and objects which hasn't got this field (getting NullPointException after get()
on this field).所以简化,我想获得nextSyncDate
大于今天的对象和没有这个字段的对象(在这个字段上get()
之后得到 NullPointException )。
I have tried something like this but it's not working like I want to..我已经尝试过这样的事情,但它并没有像我想要的那样工作..
List<MyObjects> objects;
objects.stream()
.filter(obj -> Objects.nonNull(obj.getNextSyncDate()) && obj.getNextSyncDate().before(new Date()))
On the other hand, all objects has got field counter
.另一方面,所有对象都有字段counter
。 What I want to do additionally is to set nextSyncDate
(for example for tomorrow) for every object which counter
is greater than 15. I tried to .map()
objects before .filter()
but it's also not working.我还想做的是为每个counter
大于 15 的 object 设置nextSyncDate
(例如明天)。我尝试在.filter()
之前设置.map()
对象,但它也不起作用。
When creating a stream, you are not directly modifying its source.创建 stream 时,您不会直接修改其源代码。 You need to collect the data.您需要收集数据。 Your filter seems to work as intended.您的过滤器似乎按预期工作。 I would personally not recommend having a filtered stream with side effects (do your " counter
> 15 then set nextSyncDate
" logic somewhere else) but you could do it with another stream operation such as peek
( map
is for transformation which isn't necessary in your case but could be used):我个人不建议使用带有副作用的过滤 stream (做你的“ counter
> 15然后在其他地方设置nextSyncDate
”逻辑),但你可以用另一个 stream 操作来做到这一点,例如peek
( map
中的转换是不必要的你的情况,但可以使用):
List<MyObjects> objects = /* omitted */;
List<MyObjects> filteredObjects = objects.stream()
.peek(MyObjects::setNextSycDateWithSomeLogic())
.filter(obj -> Objects.nonNull(obj.getNextSyncDate()) && obj.getNextSyncDate().before(new Date()))
.collect(Collectors.toList());
The filter can include the counter
requirement as well:过滤器也可以包括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)
The intermediate stream provided by the filter has the objects which need to be updated, so a forEach can be applied:过滤器提供的中间 stream 有需要更新的对象,因此可以应用 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));
Also, consider using LocalDate instead of deprecated Date.此外,请考虑使用 LocalDate 而不是弃用的 Date。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.