J'ai le code suivant. Sonar se plaint de remplacer cette lambda par une référence de méthode.
Stream.iterate(0, i -> i + 1).limit(100).map(i -> Integer.toString(i));
Si je le remplace par le code ci-dessous, il ne se compile pas avec une erreur de compilation: incompatibilité de type: impossible de convertir à partir de Stream<Object>
à <unknown>
.
Stream.iterate(0, i -> i + 1).limit(100).map(Integer::toString);
Comment est Integer::toString
conversion Stream<Object>
à <unknown>
?
C'est ambigu car les méthodes statique et non statiquetoString()
sont toutes deux compatibles avec la signature fonctionnelle Integer -> String
. Vous pouvez utiliser String::valueOf
au lieu.
Vous ne pouvez pas mettre Integer::toString
parce que Integer
a deux implémentations qui correspondent à l'interface fonctionnelle Function<Integer, String>
, mais vous pouvez utiliser String::valueOf
au lieu:
Stream.iterate(0, i -> i + 1)
.limit(100)
.map(String::valueOf)
.collect(Collectors.toList())
Comme mentionné par @shmosel, remplacer déjà le lambda par une référence de méthode entraînera une ambiguïté car il existe deux méthodes toString
de la signature:
parce que l'appel à Stream.iterate(0, i -> i + 1)
renvoie un Stream<Integer>
lorsque vous appelez map
avec la référence de méthode Integer::toString
le compilateur n'est pas sûr si vous vouliez faire Integer.toString(i)
ou i.toString()
d'où l'erreur de compilation.
Voici donc d'autres options par rapport à ce qui a déjà été fourni:
au lieu de Stream.iterate
, vous pouvez utiliser IntStream.iterate
puis appeler mapToObj
:
IntStream.iterate(0, i -> i + 1) // IntStream
.limit(100) // IntStream
.mapToObj(Integer::toString); // i1 -> Integer.toString(i1)
Une autre chose suggérée par intelliJ
est que vous pouvez réellement faire:
Stream.iterate(0, i -> i + 1) // Stream<Integer>
.limit(100) // Stream<Integer>
.map(Object::toString); // integer -> integer.toString()
où Object::toString
est équivalent à la lambda integer -> integer.toString()
sur une autre note, il est intéressant que Sonar propose de remplacer le lambda par une référence de méthode dans le code que vous avez montré. intelliJ IDEA était assez intelligent pour ne pas le suggérer.
Je pense que IntStream
est meilleur pour votre code:
List<String> numbers = IntStream.range(0, 100)
.mapToObj(String::valueOf)
.collect(Collectors.toList());
Ou pour votre exemple, utilisez String.valueOf
pour convertir int -> String
:
List<String> numbers = Stream.iterate(0, i -> i + 1)
.limit(100)
.map(String::valueOf)
.collect(Collectors.toList());