web-dev-qa-db-fra.com

temps de compilation: aucune instance de type variable U n'existe

L’énoncé suivant, bien que dépourvu de sens, semble syntaxiquement correct.

final Stream<LongStream> foobar = IntStream.empty()
    .flatMap(x -> IntStream.empty()
        .mapToObj(y -> IntStream.empty()
            .mapToLong(z -> 1))); //compilation error here on `z -> 1`

Cependant, il ne compile pas, en retournant:

Java: types incompatibles: type de retour incorrect dans l'expression lambda aucune instance de type variable U ne existe de sorte que Java.util.stream.Stream soit conforme à Java.util.stream.IntStream

Cependant, si vous retardez la flatmap, tout fonctionne bien:

final Stream<LongStream> foobar = IntStream.empty()
    .mapToObj(x -> IntStream.empty()
        .mapToObj(y -> IntStream.empty()
            .mapToLong(z -> 1)))
    .flatMap(x -> x);

Quelle est la difference entre .mapToObj(..).flatMap(..) et just .flatMap(..)? Est-il possible d'éliminer l'appel extra flatmap?

6
Andreas

.mapToObj(..).flatMap(..) et .flatMap(..) attendent des signatures complètement différentes.

.mapToObj(..).flatMap(..) attend une fonction int -> Object et une fonction Object -> Stream<?>.

.flatMap(..) attend une fonction int -> IntStream.

Si vous décomposez votre code, vous passez une fonction int -> Stream<LongStream>, qui n'est pas compatible avec une fonction int -> IntStream.

Vous auriez le même erreur avec ce code simplifié:

IntStream.empty().flatMap(x -> Stream.of(LongStream.empty()));
6
4castle

J'ai restructuré votre méthode pour décomposer ce qu'elle fait:

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

Nous avons deux choses qui ne vont pas ici:

Le lambda de la ligne 2 ne renvoie pas une LongStream, mais plutôt un Stream<LongStream>, car nous convertissons chaque int de notre flux en un LongStream. Si vous souhaitez que ce soit une LongStream unique, vous devez faire un flatMapToLong.

La flatMap de la ligne 3 attend une fonction int -> int, ce que la vôtre ne fait pas. Cependant, vous pouvez utiliser mapToObj à la place, qui utilise la méthode que vous fournissez.

Donc, la méthode corrigée serait:

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);
1
Joe C