Java8流:流中的通用记录器方法

Toa*_*ark 1 java functional-programming java-8 java-stream

我想创建一种在流中打印出信息的方法。请查看我现有的记录器方法。方法参数必须是通用的,例如在我的示例字符串和整数中。在我的情况下,该方法应该返回原始对象。有人可以告诉我当前方法有什么问题吗?

在此先多谢!

看一下记录器方法

Stream<String> stream = Stream.of("A", "BC", "XYZ");

stream.map(t -> logger(t.length()))
   .map(t-> logger(t.substring(0, 2)))
   .collection(Collectors.toList());

public static <T> T logger(T t) {
    System.out.println(t);
    return t;
  }
Run Code Online (Sandbox Code Playgroud)

错误:无法推断地图的类型参数(函数)

gar*_*fer 5

为什么不使用Stream#peek()?

这看起来像是您可能要使用.peek()而不是地图的示例。它是专门为打印而设计的,您无需担心会退回任何东西!

它可能看起来像:

stream.peek(it -> System.out.println(it.length))
    .peek(it -> System.out.println(it.substring(0, 2))
    // presumably other functions here before collecting...
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

在这里查看官方文档:https : //docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#peek-java.util.function.Consumer-

回到原始问题

为了解决您先前的问题,您可能想要更新函数,使其仅使用T的示例以及T的转换。您可以将其更新为:

public static <T, R> T logger(T t, Function<T, R> transform) {
  R logLine = transform.apply(t);
  System.out.println(logLine);
  return t;
}
Run Code Online (Sandbox Code Playgroud)

你的代码看起来像

stream.map(element -> logger(element, element::length)) // and so on
Run Code Online (Sandbox Code Playgroud)

  • 注意,不能保证对Java 9+执行“ peek”操作(没有愚蠢的解决方法)。 (2认同)
  • @Zircon,如果确实涉及`count()`,那么对于已知大小的情况,无需查看元素进行计数,因此它将不会运行任何阶段,也不会`peek() `。它也在javadoc中用于`count`。但是,如果您需要查看所有元素,则可以执行一次“ forEach”并查看它们。如果terminalOperation是`findFirst`或`findAny`,也不需要对所有元素都进行“ peek()”。它或多或少说明的是,您不应该使用`count`操作来计算所有元素,并且您不应该依赖于它结合使用`peek`(在大多数情况下是用于调试)。 (2认同)