如何在java-8中修改和检查是否修改?
我正在使用java-8修改一个对象如何在java-8中修改和检查是否修改?,java,java-8,Java,Java 8,我正在使用java-8修改一个对象 users.stream().filter(u -> u.count > 0).forEach(u -> u.setProperty("value")) 但是,我想知道是否有任何对象被修改过。。。i、 我想要一个布尔返回值,而这是空的 有办法吗 由于这是一个消耗性操作,因此它只能用于实际不返回任何内容的方法;也就是说,使用forEach可以确保终端操作不会返回返回值 如果要验证属性是否按您希望的方式设置,则必须再次检查元素 users.st
users.stream().filter(u -> u.count > 0).forEach(u -> u.setProperty("value"))
但是,我想知道是否有任何对象被修改过。。。i、 我想要一个布尔返回值,而这是空的
有办法吗 由于这是一个消耗性操作,因此它只能用于实际不返回任何内容的方法;也就是说,使用
forEach
可以确保终端操作不会返回返回值
如果要验证属性是否按您希望的方式设置,则必须再次检查元素
users.stream().filter(u -> u.count > 0)
.allMatch(u -> u.getProperty().equals("value"));
尽管这比其他任何事情都更能说明偏执狂;除非setProperty
有一些其他的副作用,这里没有公开,否则setter应该始终设置该值。出于验证目的,我会在单元测试中编写上述内容,但不会在生产代码中编写。添加对peek()的调用。
:
如果有任何元素通过过滤器,modified.get()
将返回true
需要使用
AtomicBoolean
(或类似内容),因为lambdas中使用的引用必须是有效的最终引用。如果我没有弄错,您想知道在执行操作时是否有匹配项。您可以简单地使用两个语句
boolean anyMatch = users.stream().anyMatch(u -> u.count > 0);
if(anyMatch) users.stream().filter(u -> u.count > 0).forEach(u -> u.setProperty("value"));
由于anyMatch
在第一个匹配元素处停止,因此只有在第一个匹配之前有一个长的非匹配元素前缀时,才会有冗余工作
如果这是一个问题,你可以使用
Spliterator<User> sp = users.stream().filter(u -> u.count > 0).spliterator();
boolean anyMatch = sp.tryAdvance(u -> u.setProperty("value"));
sp.forEachRemaining(u -> u.setProperty("value"));
Spliterator sp=users.stream().filter(u->u.count>0.Spliterator();
布尔anyMatch=sp.tryAdvance(u->u.setProperty(“值”);
sp.foreachreserving(u->u.setProperty(“值”);
相反。setProperty返回什么?一个<代码>布尔?为什么在调用了<代码> SETTABLE < /代码>之后,对象不被修改?当您调用setter时,或者当setter将其设置为以前没有的值时?是的,设置属性被视为已修改。事实上不是。@Bohemian:至少我想说,以这种方式进行检查最好还是留给单元测试,特别是考虑到
peek
确实如此。如果您要这样做的话(使用peek
),为什么不boolean modified=users.stream().filter(u->u.count>0.peek(u->u.setProperty(“value”)).count()>0;
?这不需要AtomicBoolean
。另一方面,如果使用AtomicBoolean
,则不需要peek
:users.stream().filter>(u->u.count>0).forEach(u->{modified.set(true);u.setProperty(“value”);})
@holger,因为添加了peek()
设置标志时,OP的现有代码保持不变-很容易添加和删除。它不会将修改检测嵌入主代码中-请参阅。很清楚每个流方法都在做什么以及调用它的原因。peek()
是在这种情况下使用的正确方法……除非删除终端操作后,peek
中的操作将停止工作,因此,不存在真正的“关注点分离”,但不是很明显的依赖关系。@holger如果去掉终端操作,peek就不起作用,这是好事,因为这是OP想要计数的终端操作。有一个分离的关注点:使用peek,您可以在不接触或影响任何其他代码的情况下删除计数。实际上,按照我的格式,您可以删除它它从流中通过评论出偷看线-这有多简单?阅读问题->嘿,拆分器的完美案例->写它->阅读你的答案:|->删除我的->升级你的
Spliterator<User> sp = users.stream().filter(u -> u.count > 0).spliterator();
boolean anyMatch = sp.tryAdvance(u -> u.setProperty("value"));
sp.forEachRemaining(u -> u.setProperty("value"));