Java 为什么可以';当从数组流式传输时,我是否将整数映射到字符串?
这段代码有效(取自Javadoc): IDEA告诉我“lambda表达式中有一个不兼容的返回类型字符串” 为什么??如何解决这个问题呢?Java 为什么可以';当从数组流式传输时,我是否将整数映射到字符串?,java,functional-programming,java-8,java-stream,Java,Functional Programming,Java 8,Java Stream,这段代码有效(取自Javadoc): IDEA告诉我“lambda表达式中有一个不兼容的返回类型字符串” 为什么??如何解决这个问题呢?数组.stream(int[])创建一个IntStream,而不是流。因此,在将int映射到对象时,需要调用而不仅仅是map 这应该如预期的那样起作用: String commaSeparatedNumbers = Arrays.stream(numbers) .mapToObj(i -> ((Integer) i).toString()) //i
数组.stream(int[])
创建一个IntStream
,而不是流。因此,在将int
映射到对象时,需要调用而不仅仅是map
这应该如预期的那样起作用:
String commaSeparatedNumbers = Arrays.stream(numbers)
.mapToObj(i -> ((Integer) i).toString()) //i is an int, not an Integer
.collect(Collectors.joining(", "));
你也可以写:
String commaSeparatedNumbers = Arrays.stream(numbers)
.mapToObj(Integer::toString)
.collect(Collectors.joining(", "));
Arrays.stream(numbers)
在引擎盖下创建一个IntStream
,而IntStream
上的映射操作需要一个IntUnaryOperator
(即一个函数int->int
)。要应用的映射函数不遵守此约定,因此存在编译错误
您需要在之前调用boxed()
,以获取流(这是Arrays.asList(…).Stream()
返回的内容)。然后像在第一个代码片段中那样调用map
请注意,如果需要boxed()
后跟map
,则可能需要直接使用mapToObj
优点是mapToObj
不需要将每个int
值都框到Integer
对象中;当然,这取决于您应用的映射函数;因此,我会使用这个选项,它的编写时间也更短。您可以使用Arrays.Stream(int[])创建一个整数流,您可以调用mapToObj
像mapToObj(Integer::toString)
希望这对您有所帮助。如果此示例和问题的目的是了解如何将字符串映射到int流(例如,使用int流访问字符串数组中的索引),您也可以使用装箱,然后强制转换为int(这将允许访问数组的索引)
.boxed()调用将IntStream(一个基本int流)转换为一个流(一个对象流——即整数对象),然后该流将接受lambda返回的对象(在本例中是字符串对象)。在这里,它只是一个用于演示的数字的字符串表示形式,但它也可以很容易(更实际)成为任何字符串对象——就像前面提到的字符串数组的元素一样
我只是想提供另一种可能性。在编程中,完成一项任务总是有多种方法。尽可能多地了解,然后选择最适合手头任务的一个,记住性能问题、直观性、代码清晰性、您对编码风格的偏好以及最自我记录
快乐编码 没有装箱、AFAIK,也没有添加到堆中的小字符串爆炸:
public static void main(String[] args) {
IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6);
String s = stream.collect(StringBuilder::new, (builder, n) -> builder.append(',').append(n), (x, y) -> x.append(',').append(y)).substring(1);
System.out.println(s);
}
IntStream
和Stream
之间有什么区别?@FlorianMargaine AnIntStream
是对原始int
值的流专门化。Stream
只是一个包含Integer
对象的流。@FlorianMargaineIntStream
是一个流或原语(ints),而Steram
是一个对象流。出于性能原因,原始流有专门的方法。IntStream.mapToObj
需要一个IntFunction
,这是一个使用int
值的函数 .mapToObj((整数i)->i.toString())
不起作用。无论如何,不建议使用它,因为它包含从int
到Integer
的不必要转换。相反,.mapToObj(Integer::toString)
工作得很好,因为它将调用静态
方法Integer.toString(int)
。请注意,这与在服务器上调用.map(Integer::toString)
不同 <代码>流
因为后者不明确,所以无法编译。@cic:no,在流
上调用.map(Integer::toString)
确实不明确,因为.map(i->i.toString())
和.map(i->Integer.toString(i))
都是有效的。但是,使用.map(Object::toString)
很容易解决这个问题。您正在做不必要的工作。将每个int
装箱到其包装类型Integer
,然后将其取消装箱。
String commaSeparatedNumbers = Arrays.stream(numbers)
.mapToObj(Integer::toString)
.collect(Collectors.joining(", "));
String csn = Arrays.stream(numbers) // your numbers array
.mapToObj(Integer::toString)
.collect(Collectors.joining(", "));
int[] numbers = {0, 1, 2, 3};
String commaSeparatedNumbers = Arrays.stream(numbers)
.boxed()
.map((Integer i) -> Integer.toString((int)i))
.collect(Collectors.joining(", "));
public static void main(String[] args) {
IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6);
String s = stream.collect(StringBuilder::new, (builder, n) -> builder.append(',').append(n), (x, y) -> x.append(',').append(y)).substring(1);
System.out.println(s);
}