Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java8 streams: generic logger method in stream

I want to create a method that prints out information within a stream. Please take a look at my existing logger method. The method arguments have to be generic like in my example string & integer. The method is supposed to return the original object, in my case string. Can someone tell me what's wrong with my current method?

Thanks a lot in advance!

look at the logger-method

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;
  }

ERROR: Cannot infer type argument(s) for map(Function)

like image 281
Toark Avatar asked Jun 13 '26 09:06

Toark


1 Answers

Why not use Stream#peek()?

This looks like an example of where you might want to use .peek() instead of a map. It's specifically built for printing out, and you don't need to worry about returning anything!

It might look more like:

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());

Take a look at the official documentation here: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#peek-java.util.function.Consumer-

Back to the Original Question

To address your previous question, you probably want to update your function so that it takes a pure example of T, and a transform for T. You can update it to look like:

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

and your code will look like

stream.map(element -> logger(element, element::length)) // and so on
like image 185
gar.stauffer Avatar answered Jun 14 '26 22:06

gar.stauffer