I don't understand this Java construct that I'm seeing in the documentation here.
The part that I think I understand but cannot seem to replicate is the example:
public static <W> HttpResponse.BodySubscriber<Supplier<W>> asJSON(Class<W> targetType) {
HttpResponse.BodySubscriber<InputStream> upstream = HttpResponse.BodySubscribers.ofInputStream();
HttpResponse.BodySubscriber<Supplier<W>> downstream = HttpResponse.BodySubscribers.mapping(
upstream,
(InputStream is) -> () -> {
try (InputStream stream = is) {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(stream, targetType);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
);
return downstream;
}
Specifically the (InputStream is) -> () -> {
part. When I read it I think it should be a Supplier
that provides a Function
that does what it does. However, when I try to code such a thing myself it doesn't work.
public static void main(String[] args) throws IOException {
String r = myMethod((String s)->()->{return s + "ddd";});
}
public static String myMethod(Function<String, String> func) {
return func.apply("Hello");
}
Gives me the compile err Target type of a lambda conversion must be an interface
. However, Function
is an interface.
What do I not understand?
HttpResponse.BodySubscribers.mapping takes as a 2nd parameter a value of type Function<? super T,? extends U>
. In your code T
is InputStream
and U
is Supplier<W>
, so the full type of mapping
would be (ignoring the super
\extends
for brevity):
Function<InputStream, Supplier<W>>
Since a Supplier<W>
has a single method of type W get()
, a lambda expression for the Supplier
type would be:
() -> {/* return a value of type W*/}
and therefore a lambda expression for mapper
would be:
(InputStream is) -> () -> {/* return a value of type W*/}
which matches your code.