将此 lambda 替换为方法引用
Replace this lambda with a method reference
我有以下代码。 Sonar 抱怨用方法引用替换此 lambda。
Stream.iterate(0, i -> i + 1).limit(100).map(i -> Integer.toString(i));
如果我用下面的代码替换它,它不会编译并出现编译错误:类型不匹配:无法从 Stream<Object>
转换为 <unknown>
。
Stream.iterate(0, i -> i + 1).limit(100).map(Integer::toString);
Integer::toString
如何将 Stream<Object>
转换为 <unknown>
?
这是不明确的,因为 static and non-static toString()
方法都与函数签名 Integer -> String
兼容。您可以改用 String::valueOf
。
你不能放Integer::toString
因为Integer
有两个适合功能接口Function<Integer, String>
的实现,但你可以用String::valueOf
代替:
Stream.iterate(0, i -> i + 1)
.limit(100)
.map(String::valueOf)
.collect(Collectors.toList())
正如@shmosel 所提到的,已经用方法引用替换了 lambda 会导致歧义,因为签名有两个 toString
方法:
因为调用 Stream.iterate(0, i -> i + 1)
returns a Stream<Integer>
当您使用方法引用 map
调用 Integer::toString
时,编译器不确定您的意思是否做 Integer.toString(i)
或 i.toString()
因此编译错误。
因此,这里是已提供内容的其他选项:
而不是 Stream.iterate
你可以使用 IntStream.iterate
然后调用 mapToObj
:
IntStream.iterate(0, i -> i + 1) // IntStream
.limit(100) // IntStream
.mapToObj(Integer::toString); // i1 -> Integer.toString(i1)
intelliJ
建议的另一件事是您实际上可以这样做:
Stream.iterate(0, i -> i + 1) // Stream<Integer>
.limit(100) // Stream<Integer>
.map(Object::toString); // integer -> integer.toString()
其中 Object::toString
等价于 lambda integer -> integer.toString()
另一方面,有趣的是,Sonar 建议在您显示的代码中将 lambda 替换为方法引用。 intelliJ IDEA 很聪明,没有建议它。
我认为 IntStream
更适合您的代码:
List<String> numbers = IntStream.range(0, 100)
.mapToObj(String::valueOf)
.collect(Collectors.toList());
或者对于您的示例,请使用 String.valueOf
转换 int -> String
:
List<String> numbers = Stream.iterate(0, i -> i + 1)
.limit(100)
.map(String::valueOf)
.collect(Collectors.toList());
我有以下代码。 Sonar 抱怨用方法引用替换此 lambda。
Stream.iterate(0, i -> i + 1).limit(100).map(i -> Integer.toString(i));
如果我用下面的代码替换它,它不会编译并出现编译错误:类型不匹配:无法从 Stream<Object>
转换为 <unknown>
。
Stream.iterate(0, i -> i + 1).limit(100).map(Integer::toString);
Integer::toString
如何将 Stream<Object>
转换为 <unknown>
?
这是不明确的,因为 static and non-static toString()
方法都与函数签名 Integer -> String
兼容。您可以改用 String::valueOf
。
你不能放Integer::toString
因为Integer
有两个适合功能接口Function<Integer, String>
的实现,但你可以用String::valueOf
代替:
Stream.iterate(0, i -> i + 1)
.limit(100)
.map(String::valueOf)
.collect(Collectors.toList())
正如@shmosel 所提到的,已经用方法引用替换了 lambda 会导致歧义,因为签名有两个 toString
方法:
因为调用 Stream.iterate(0, i -> i + 1)
returns a Stream<Integer>
当您使用方法引用 map
调用 Integer::toString
时,编译器不确定您的意思是否做 Integer.toString(i)
或 i.toString()
因此编译错误。
因此,这里是已提供内容的其他选项:
而不是 Stream.iterate
你可以使用 IntStream.iterate
然后调用 mapToObj
:
IntStream.iterate(0, i -> i + 1) // IntStream
.limit(100) // IntStream
.mapToObj(Integer::toString); // i1 -> Integer.toString(i1)
intelliJ
建议的另一件事是您实际上可以这样做:
Stream.iterate(0, i -> i + 1) // Stream<Integer>
.limit(100) // Stream<Integer>
.map(Object::toString); // integer -> integer.toString()
其中 Object::toString
等价于 lambda integer -> integer.toString()
另一方面,有趣的是,Sonar 建议在您显示的代码中将 lambda 替换为方法引用。 intelliJ IDEA 很聪明,没有建议它。
我认为 IntStream
更适合您的代码:
List<String> numbers = IntStream.range(0, 100)
.mapToObj(String::valueOf)
.collect(Collectors.toList());
或者对于您的示例,请使用 String.valueOf
转换 int -> String
:
List<String> numbers = Stream.iterate(0, i -> i + 1)
.limit(100)
.map(String::valueOf)
.collect(Collectors.toList());