此代码有效(在Javadoc中使用):
List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
String commaSeparatedNumbers = numbers.stream()
.map(i -> i.toString())
.collect(Collectors.joining(", "));
这个不能编译:
int[] numbers = {1, 2, 3, 4};
String commaSeparatedNumbers = Arrays.stream(numbers)
.map((Integer i) -> i.toString())
.collect(Collectors.joining(", "));
IDEA告诉我,我在lambda表达式&#34;中有一个&#34;不兼容的返回类型字符串。
为什么?以及如何解决这个问题?
答案 0 :(得分:102)
Arrays.stream(int[])
创建IntStream
,而不是Stream<Integer>
。因此,在将map
映射到对象时,您需要致电mapToObj
而不是int
。
这应该按预期工作:
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(", "));
答案 1 :(得分:19)
Arrays.stream(numbers)
在底层创建IntStream
,IntStream
上的地图操作需要IntUnaryOperator
(即函数int -> int
)。您要应用的映射函数不遵守此契约,因此也不符合编译错误。
您需要先调用boxed()
才能获得Stream<Integer>
(这是Arrays.asList(...).stream()
返回的内容)。然后像在第一个代码段中那样拨打map
。
请注意,如果您需要boxed()
后跟map
,则可能需要直接使用mapToObj
。
优点是mapToObj
不需要将每个int
值封装到Integer
个对象;取决于你当然适用的映射功能;所以我会选择这个也更短的选项。
答案 2 :(得分:4)
您可以使用Arrays.stream(int [])创建整数流,您可以像mapToObj
一样调用mapToObj(Integer::toString)
。
String csn = Arrays.stream(numbers) // your numbers array
.mapToObj(Integer::toString)
.collect(Collectors.joining(", "));
希望这会有所帮助..
答案 3 :(得分:1)
如果此示例和问题的目的是弄清楚如何将字符串映射到int流(例如,使用int流来访问字符串数组中的索引),您还可以使用装箱,然后转换为int(然后允许访问数组的索引)。
int[] numbers = {0, 1, 2, 3};
String commaSeparatedNumbers = Arrays.stream(numbers)
.boxed()
.map((Integer i) -> Integer.toString((int)i))
.collect(Collectors.joining(", "));
.boxed()调用将IntStream(原始int的流)转换为Stream(对象流 - 即Integer对象),然后接受对象的返回(在本例中为String)来自你的lambda。这里只是用于演示目的的数字的字符串表示,但它可以很容易(并且更实际地)是任何字符串对象 - 如前面提到的字符串数组的元素。
以为我会提供另一种可能性。在编程中,总有多种方法可以完成任务。尽可能多地了解,然后选择最适合手头任务的那个,记住性能问题,直观性,代码清晰度,编码风格偏好以及最自我记录。
快乐的编码!
答案 4 :(得分:0)
没有拳击,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);
}