英文:
Stream.flatMap() from char[] to Character stream
问题
import java.util.*;
import java.util.stream.*;
class Playground {
public static void main(String[] args) {
// Creating a character array
char arr[] = { '1', '2', '3', '4', '5' };
// --------- Using Stream.of() ---------
// Will work efficiently
// to convert int array into Stream
Stream<char[]> stream = Stream.of(arr);
Stream<Character> s = stream.flatMap(item -> new String(item).chars().mapToObj(a -> (char) a));
// Displaying elements in Stream
s.forEach(str -> System.out.print(str + " "));
}
}
I'm trying to convert a char[] into a stream of Characters with flatMap() but I got the following error
./Playground/Playground.java:14: error: incompatible types: inference variable R has incompatible bounds
Stream<Integer> s = stream.flatMap((item) -> new String(item).chars().mapToObj(a -> (char) a));
^
equality constraints: Integer
lower bounds: U,Character
where R,T,U are type-variables:
R extends Object declared in method <R>flatMap(Function<? super T,? extends Stream<? extends R>>)
T extends Object declared in interface Stream
U extends Object declared in method <U>mapToObj(IntFunction<? extends U>)
1 error
Need help with understanding the error and how to accomplish this task. Specifically how to fix this line of code using flatMap() from char[] to Character stream.
Edit: So the problem turns out not to be about Stream but the lambda expression, and I messed up the typing after fixing the lambda expression by accident. The original line was:
Stream<Character> s = stream.flatMap(item -> { new String(item).chars().mapToObj(a -> (char) a); });
The issue was a missing return statement inside {}. Then I altered the line to:
Stream<Integer> s = stream.flatMap(item -> new String(item).chars());
because I thought IntStream::mapToObj was causing troubles. However, I forgot the boxed() at the end and got another type error. So I added back the IntStream::mapToObj and posted the question, but forgot to change the Stream type back to Character. I got confused, but the fog is cleared now. Thanks for the good answers.
英文:
import java.util.*;
import java.util.stream.*;
class Playground {
public static void main(String[] args)
{
// Creating a character array
char arr[] = { '1', '2', '3', '4', '5' };
// --------- Using Stream.of() ---------
// Will work efficiently
// to convert int array into Stream
Stream<char[]> stream = Stream.of(arr);
Stream<Integer> s = stream.flatMap((item)->new String(item).chars().mapToObj(a->(char)a));
// Displaying elements in Stream
s.forEach(str -> System.out.print(str + " "));
}
}
I'm trying to convert a char[] into a stream of Characters with flatMap() but I got the following error
./Playground/Playground.java:14: error: incompatible types: inference variable R has incompatible bounds
Stream<Integer> s = stream.flatMap((item)->new String(item).chars().mapToObj(a->(char)a));
^
equality constraints: Integer
lower bounds: U,Character
where R,T,U are type-variables:
R extends Object declared in method <R>flatMap(Function<? super T,? extends Stream<? extends R>>)
T extends Object declared in interface Stream
U extends Object declared in method <U>mapToObj(IntFunction<? extends U>)
1 error
Need help with understanding the error and how to accomplish this task. Specifically how this fix this line of code using flatMap() from char[] to Character stream.
Stream<Integer> s = stream.flatMap((item)->new String(item).chars().mapToObj(a->(char)a))
Edit: So the problems turns out not to be about Stream but lambda expression and I twitched the line and messed the typing up after fixing the lambda expression by accident. The original line was
Stream<Character> s = stream.flatMap(item->{new String(item).chars().mapToObj(a->(char)a);});
and the issue was missing return statement inside {}. Then I altered the line to
Stream<Integer> s = stream.flatMap((item)->new String(item).chars())
because I thought IntStream::mapToObj was causing troubles however I forgot the boxed() in the end and got another type error so I added back the IntStream::mapToObj and posted the question but forgot to change the Stream type back to Character. I got confused but the fog is cleared now.Thanks for the good answers.
答案1
得分: 2
你就快成功了。只需将 Stream<Integer>
替换为 Stream<Character>
,因为你在代码中进行了 char
强制转换。
然而,关于你的代码问题在于你不必要地进行了 flatMap
操作。Stream.of
需要一个具有引用类型的数组作为其复合类型。此外,Arrays.stream
没有针对 char[]
的重载。你最终会在一个保证只有一个元素的内容上进行流处理。这个元素就是你的 char[]
。
你可以直接省略 flatMap
操作,直接将 char 数组转换为 String。
String str = new String(arr);
Stream<Character> characterStream = str.chars().mapToObj(c -> (char) c);
英文:
You were almost there. Just replace Stream<Integer>
to Stream<Character>
, as you are casting to a char
in your code.
However, the problem about your code is that you are unnecessarily flatMap
ping. Stream.of
expects an array with a reference type as its compound type. Further, Arrays.stream
does not have an overload for char[]
. You end up streaming over something that is guaranteed to be a single element. That element is your char[]
.
You could just drop the flatMap
operation, and directly convert the char array to a String.
String str = new String(arr);
Stream<Character> characterStream = str.chars().mapToObj(c -> (char) c);
答案2
得分: 2
以下是翻译好的内容:
对于你在这些不必要操作的绕行中想要实现的目标并不明确。当你想要在一个数组上进行流处理时,直接从该操作开始,而不是创建一个单元素流,然后链接flatMap
,再链接另一个map
。
你的代码已经包含了在其他操作中间对char[]
数组进行流处理的方法,使用了String
构造函数。
char[] arr = { '1', '2', '3', '4', '5' };
new String(arr).chars().forEach(i -> System.out.print(i + " "));
这将打印出Unicode数字。如果你想要打印字符,只需更改终端操作:
new String(arr).chars().forEach(i -> System.out.print((char)i + " "));
或者
new String(arr).chars().forEach(i -> System.out.printf("%c ", i));
你还可以使用
new String(arr).chars().mapToObj(i -> (char)i).forEach(i -> System.out.print(i + " "));
但这会带来装箱开销,因为它会创建一个Stream<Character>
。
注意,new String(arr)
会产生复制开销,因为它创建了一个不可变对象。你可以通过使用以下方法避免这种情况:
CharBuffer.wrap(arr).chars().forEach(i -> System.out.printf("%c ", i));
当然,你可以插入任意数量的花括号,例如:
Stream.of(arr)
.flatMapToInt(array -> CharBuffer.wrap(array).chars())
.mapToObj(i -> (char)i) // 返回一个Stream<Character>而不是Stream<Integer>
.forEach(i -> System.out.printf("%c ", i));
但没有理由这样做。
英文:
It’s not clear what you are trying to achieve with this detour of unnecessary operations. When you want to stream over an array, just start with that operation, instead of creating a single element stream, to chain flatMap
, to chain another map
.
Your code does already contain an approach for streaming over a char[]
array, in the middle of the other operations, using the String
constructor.
char[] arr = { '1', '2', '3', '4', '5' };
new String(arr).chars().forEach(i -> System.out.print(i + " "));
This will print the Unicode numbers. When you want to print characters instead, just change the terminal operation:
new String(arr).chars().forEach(i -> System.out.print((char)i + " "));
or
new String(arr).chars().forEach(i -> System.out.printf("%c ", i));
You can also use
new String(arr).chars().mapToObj(i -> (char)i).forEach(i -> System.out.print(i+" "));
but this bears boxing overhead, as it creates a Stream<Character>
.
Note that new String(arr)
bears a copying overhead, as it creates an immutable object. You can avoid this by using
CharBuffer.wrap(arr).chars().forEach(i -> System.out.printf("%c ", i));
Of course, you can insert as many curlicues as you want, e.g.
Stream.of(arr)
.flatMapToInt(array -> CharBuffer.wrap(array).chars())
.mapToObj(i -> (char)i) // returns a Stream<Character> not Stream<Integer>
.forEach(i -> System.out.printf("%c ", i));
but there is no reason to do so.
答案3
得分: 1
- 对于除了byte、char或short之外的任何数组,您可以使用
Arrays.stream()
。 - 对于任何Int、Double或Long类型的基本数组,您可以使用
*Stream.of()
,其中*是Int、Double或Long。 - 对于任何对象数组,您可以使用
Stream.of()
。
以下所有内容都按照上述解释进行工作。
Integer[] IntegerArray = {1,2,3,4};
Arrays.stream(IntegerArray).forEach(System.out::println);
Stream.of(IntegerArray).forEach(System.out::println);
int[] intArray = {1,2,3,4};
Arrays.stream(intArray).forEach(System.out::println);
IntStream.of(intArray).forEach(System.out::println);
double[] doubleArray = {1.2,3.3,4.5,6.7};
Arrays.stream(doubleArray).forEach(System.out::println);
DoubleStream.of(doubleArray).forEach(System.out::println);
String[] stringArray = {"a","b","c","d"};
Stream.of(stringArray).forEach(System.out::println);
要解决您的实际问题,请尝试以下方法。
// 创建字符数组
char arr[] = { '1', '2', '3', '4', '5' };
// --------- 使用 Stream.of() ---------
// 将高效地工作
// 转换字符数组为Stream
Stream<char[]> stream = Stream.of(arr);
// 在Stream中显示元素
stream.forEach(str -> System.out.print(str + " "));
Stream<Integer> s = stream.flatMapToInt((item) -> (new String(item)).chars()).boxed();
// 或者
IntStream s = stream.flatMapToInt((item) -> (new String(item)).chars());
// 在Stream中显示元素
s.forEach(str -> System.out.print((char)str + " "));
英文:
- You can use
Arrays.stream()
for any array except byte, char or short. - You can use
*Stream.of()
for any primitive array of type * where * is Int or Double, or Long. - You can use
Stream.of()
for any Object array.
All of the following work as explained above.
Integer[] IntegerArray = {1,2,3,4};
Arrays.stream(IntegerArray).forEach(System.out::println);
Stream.of(IntegerArray).forEach(System.out::println);
int[] intArray = {1,2,3,4};
Arrays.stream(intArray).forEach(System.out::println);
IntStream.of(intArray).forEach(System.out::println);
double[] doubleArray = {1.2,3.3,4.5,6.7};
Arrays.stream(doubleArray).forEach(System.out::println);
DoubleStream.of(doubleArray).forEach(System.out::println);
String[] stringArray = {"a","b","c","d"};
Stream.of(stringArray).forEach(System.out::println);
To solve your actual problem, try this.
// Creating a character array
char arr[] = { '1', '2', '3', '4', '5' };
// --------- Using Stream.of() ---------
// Will work efficiently
// to convert int array into Stream
Stream<char[]> stream = Stream.of(arr);
// Displaying elements in Stream
s.forEach(str -> System.out.print(str + " "));
Stream<Integer> s = stream.flatMapToInt((item)->(new String(item)).chars()).boxed();
//or
IntStream s = stream.flatMapToInt((item)->(new String(item)).chars());
// Displaying elements in Stream
s.forEach(str -> System.out.print((char)str + " "));
</details>
# 答案4
**得分**: 1
以下是翻译好的部分:
你使用了 `Stream<Integer>`,而不是 `Stream<Character>`。如果你想使用 `Stream<Integer>`,你需要使用 [IntStream::boxed][1] 或者像下面展示的那样使用 `mapToObj(a -> Integer.valueOf(a))`:
```java
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
char arr[] = { '1', '2', '3', '4', '5' };
Stream<char[]> stream1 = Stream.of(arr);
Stream<Character> chars = stream1.flatMap(item -> new String(item).chars().mapToObj(a -> (char) a));
chars.forEach(c -> System.out.print(c + " "));
System.out.println();
Stream<char[]> stream2 = Stream.of(arr);
Stream<Integer> ints = stream2.flatMap(item -> new String(item).chars().boxed());
ints.forEach(i -> System.out.print(i + " "));
System.out.println();
Stream<char[]> stream3 = Stream.of(arr);
Stream<Integer> integers = stream3.flatMap(item -> new String(item).chars().mapToObj(a -> Integer.valueOf(a)));
integers.forEach(i -> System.out.print(i + " "));
}
}
输出:
1 2 3 4 5
49 50 51 52 53
49 50 51 52 53
英文:
You have used Stream<Integer>
instead of Stream<Character>
. If you want to use Stream<Integer>
, you need to use IntStream::boxed or mapToObj(a -> Integer.valueOf(a))
as shown below:
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
char arr[] = { '1', '2', '3', '4', '5' };
Stream<char[]> stream1 = Stream.of(arr);
Stream<Character> chars = stream1.flatMap(item -> new String(item).chars().mapToObj(a -> (char) a));
chars.forEach(c -> System.out.print(c + " "));
System.out.println();
Stream<char[]> stream2 = Stream.of(arr);
Stream<Integer> ints = stream2.flatMap(item -> new String(item).chars().boxed());
ints.forEach(i -> System.out.print(i + " "));
System.out.println();
Stream<char[]> stream3 = Stream.of(arr);
Stream<Integer> integers = stream3.flatMap(item -> new String(item).chars().mapToObj(a -> Integer.valueOf(a)));
integers.forEach(i -> System.out.print(i + " "));
}
}
Output:
1 2 3 4 5
49 50 51 52 53
49 50 51 52 53
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论