在java流中,使用.peek()被认为仅用于调试目的,是否将日志记录视为调试?

Jon*_*nas 5 java java-8 java-stream

所以我有一个对象列表,我想要处理部分或整体,我想记录那些已处理的对象.

考虑一个虚构的例子:

List<ClassInSchool> classes;
classes
.stream()
.filter(verifyClassInSixthGrade())
.filter(classHasNoClassRoom())
.peek(classInSchool -> log.debug("Processing classroom {} in sixth grade without classroom.", classInSchool)
.forEach(findMatchingClassRoomIfAvailable());
Run Code Online (Sandbox Code Playgroud)

在这种情况下使用.peek()会被视为无意中使用API​​吗?

为了进一步解释,在这个问题中,关键点是:"不要以非预期的方式使用API​​,即使它实现了你的直接目标." 我的问题是,是否每次使用peek,调试你的流,直到你验证了整个链的工作设计并再次删除了.peek(),这是非预期的用途.因此,如果将其用作记录流实际处理的每个对象的方法,则会被视为意外使用.

Hol*_*ger 5

文档peek将意图描述为

此方法的存在主要是为了支持调试,您希望在其中查看元素流经管道中的某个点时的情况。

表单的表达.peek(classInSchool -> log.debug("Processing classroom {} in sixth grade without classroom.", classInSchool)满足了这个意图,因为它是关于报告元素的处理。无论您是使用日志框架还是仅打印语句都没有关系,如文档示例中的.peek(e -> System.out.println("Filtered value: " + e)). 在任何一种情况下,意图都很重要,而不是技术方法。如果有人peek意图打印所有元素,即使使用与文档示例 ( System.out.println)相同的技术方法,也是错误的。

该文档并不要求您必须区分生产环境或调试环境,以删除peek前者的用法。实际上,您的使用甚至可以实现这一点,因为日志记录框架允许您通过可配置的日志记录级别使该操作静音。

我仍然建议记住,对于某些管道,插入peek操作可能会比实际操作插入更多的开销(或在这种程度上阻碍 JVM 的循环优化)。但是,如果您没有遇到性能问题,您可以遵循旧建议,除非您有真正的原因,否则不要尝试优化……