Java 从数组流式传输时,为什么不能将整数映射到字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29028980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't I map integers to strings when streaming from an array?
提问by Denys Séguret
This code works (taken in the Javadoc):
此代码有效(取自 Javadoc):
List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
String commaSeparatedNumbers = numbers.stream()
.map(i -> i.toString())
.collect(Collectors.joining(", "));
This one can't be compiled:
这个不能编译:
int[] numbers = {1, 2, 3, 4};
String commaSeparatedNumbers = Arrays.stream(numbers)
.map((Integer i) -> i.toString())
.collect(Collectors.joining(", "));
IDEA tells me I have an "incompatible return type String in lambda expression".
IDEA 告诉我我在 lambda 表达式中有一个“不兼容的返回类型字符串”。
Why ? And how to fix that ?
为什么 ?以及如何解决这个问题?
采纳答案by assylias
Arrays.stream(int[])
creates an IntStream
, not a Stream<Integer>
. So you need to call mapToObj
instead of just map
, when mapping an int
to an object.
Arrays.stream(int[])
创建一个IntStream
,而不是一个Stream<Integer>
。因此,在将 an 映射到对象时,您需要调用mapToObj
而不仅仅是map
, int
。
This should work as expected:
这应该按预期工作:
String commaSeparatedNumbers = Arrays.stream(numbers)
.mapToObj(i -> ((Integer) i).toString()) //i is an int, not an Integer
.collect(Collectors.joining(", "));
which you can also write:
你也可以写:
String commaSeparatedNumbers = Arrays.stream(numbers)
.mapToObj(Integer::toString)
.collect(Collectors.joining(", "));
回答by Alexis C.
Arrays.stream(numbers)
creates an IntStream
under the hood and the map operation on an IntStream
requires an IntUnaryOperator
(i.e a function int -> int
). The mapping function you want to apply does not respect this contract and hence the compilation error.
Arrays.stream(numbers)
IntStream
在幕后创建一个,并且对 an 的映射操作IntStream
需要一个IntUnaryOperator
(即一个函数int -> int
)。您要应用的映射函数不遵守此约定,因此会出现编译错误。
You would need to call boxed()
before in order to get a Stream<Integer>
(this is what Arrays.asList(...).stream()
returns). Then just call map
as you did in the first snippet.
您需要在boxed()
之前调用才能获得一个Stream<Integer>
(这是Arrays.asList(...).stream()
返回的内容)。然后就像map
你在第一个片段中所做的那样调用。
Note that if you need boxed()
followed by map
you probably want to use mapToObj
directly.
请注意,如果您需要boxed()
跟随,map
您可能想mapToObj
直接使用。
The advantage is that mapToObj
doesn't require to box each int
value to an Integer
object; depending on the mapping function you apply of course; so I would go with this option which is also shorter to write.
优点是mapToObj
不需要将每个int
值装箱到一个Integer
对象;当然,这取决于您应用的映射函数;所以我会选择这个写起来也更短的选项。
回答by codebot
You can create an Integer Stream using Arrays.stream(int[]) , you can call mapToObj
like mapToObj(Integer::toString)
.
您可以使用 Arrays.stream(int[]) 创建一个整数流,您可以调用mapToObj
like mapToObj(Integer::toString)
。
String csn = Arrays.stream(numbers) // your numbers array
.mapToObj(Integer::toString)
.collect(Collectors.joining(", "));
Hope this helps..
希望这可以帮助..
回答by jamesc1101
If the purpose of this sample and question is to figure out how to map strings to a stream of ints (for example, using a stream of ints to access an index in an Array of strings), you can also use boxing, then casting to an int (which would then allow accessing the index of the array).
如果此示例和问题的目的是弄清楚如何将字符串映射到整数流(例如,使用整数流访问字符串数组中的索引),您还可以使用装箱,然后强制转换为一个 int (然后允许访问数组的索引)。
int[] numbers = {0, 1, 2, 3};
String commaSeparatedNumbers = Arrays.stream(numbers)
.boxed()
.map((Integer i) -> Integer.toString((int)i))
.collect(Collectors.joining(", "));
The .boxed() call converts your IntStream (a stream of primitive ints) to a Stream (a stream of objects -- namely, Integer objects) which will then accept the return of an object (in this case, a String object) from your lambda. Here it is just a string representation of the number for demonstration purposes, but it could just as easily (and more practically) be any string object -- like the element of a string array as mentioned before.
.boxed() 调用将您的 IntStream(原始整数流)转换为 Stream(对象流——即 Integer 对象),然后它将接受从你的拉姆达。这里它只是用于演示目的的数字的字符串表示,但它也可以很容易(并且更实际地)是任何字符串对象——就像前面提到的字符串数组的元素一样。
Just thought I'd offer another possibility. In programming, there are always multiple ways of accomplishing a task. Know as many as you can, then choose the one that fits the best for the task at hand, keeping in mind performance issues, intuitiveness, clarity of code, your preferences in coding style, and the most self-documenting.
只是想我会提供另一种可能性。在编程中,总是有多种方法可以完成一项任务。尽可能多地了解,然后选择最适合手头任务的方法,同时牢记性能问题、直观性、代码清晰度、您对编码风格的偏好以及最自我记录的方式。
Happy coding!
快乐编码!
回答by AbuNassar
No boxing, AFAIK, and no explosion of little strings added to the heap:
没有拳击,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);
}