La siguiente declaración, aunque sin sentido, parece sintácticamente sólida.
final Stream<LongStream> foobar = IntStream.empty() .flatMap(x -> IntStream.empty() .mapToObj(y -> IntStream.empty() .mapToLong(z -> 1))); //compilation error here on `z -> 1`Sin embargo, no compila, devolviendo:
java: tipos incompatibles: tipo de retorno incorrecto en la expresión lambda no existen instancias de variable de tipo U para que java.util.stream.Stream se ajuste a java.util.stream.IntStream
Sin embargo, si retrasa el mapa plano, todo funciona bien:
final Stream<LongStream> foobar = IntStream.empty() .mapToObj(x -> IntStream.empty() .mapToObj(y -> IntStream.empty() .mapToLong(z -> 1))) .flatMap(x -> x); ¿Cuál es la diferencia entre .mapToObj(..).flatMap(..) y simplemente .flatMap(..) ? ¿Hay alguna forma de eliminar la llamada de mapa plano adicional?
.mapToObj(..).flatMap(..) y .flatMap(..) esperan firmas completamente diferentes.
.mapToObj(..).flatMap(..) espera una función int -> Object y una función Object -> Stream<?> .
.flatMap(..) espera una función int -> IntStream .
Si desglosa su código, está pasando una función int -> Stream<LongStream> , que no es compatible con una función int -> IntStream .
Tendrías el mismo error con este código simplificado:
IntStream.empty().flatMap(x -> Stream.of(LongStream.empty()));He refactorizado tu método para desglosar lo que está haciendo:
IntFunction<LongStream> f1 = y -> IntStream.empty().mapToLong(z -> 1); IntFunction<LongStream> f2 = x -> IntStream.empty().mapToObj(f1); final Stream<LongStream> foobar = IntStream.empty().flatMap(f2);Tenemos dos cosas mal aquí:
La lambda en la línea 2 no devuelve un LongStream , sino un Stream<LongStream> , ya que estamos convirtiendo cada int en nuestro flujo en un LongStream . Si tiene la intención de que sea un LongStream único, debe hacer un flatMapToLong .
flatMap en la línea 3 espera una función int -> int , que no es la tuya. Sin embargo, puede usar mapToObj en su lugar, que toma el método que está proporcionando.
Entonces el método corregido sería:
IntFunction<LongStream> f1 = y -> IntStream.empty().mapToLong(z -> 1); IntFunction<LongStream> f2 = x -> IntStream.empty().mapToObj(f1).flatMapToLong(i -> i); final Stream<LongStream> foobar = IntStream.empty().mapToObj(f2);