`Stream.flatMap()` 从字符数组转换为字符流。

huangapple go评论74阅读模式
英文:

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[] = { &#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39; }; 
  
        // --------- Using Stream.of() --------- 
        // Will work efficiently 
  
        // to convert int array into Stream 
        Stream&lt;char[]&gt; stream = Stream.of(arr); 
        Stream&lt;Integer&gt; s = stream.flatMap((item)-&gt;new String(item).chars().mapToObj(a-&gt;(char)a));
  
        // Displaying elements in Stream 
        s.forEach(str -&gt; System.out.print(str + &quot; &quot;)); 
    } 
} 

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&lt;Integer&gt; s = stream.flatMap((item)-&gt;new String(item).chars().mapToObj(a-&gt;(char)a));
                                          ^
    equality constraints: Integer
    lower bounds: U,Character
  where R,T,U are type-variables:
    R extends Object declared in method &lt;R&gt;flatMap(Function&lt;? super T,? extends Stream&lt;? extends R&gt;&gt;)
    T extends Object declared in interface Stream
    U extends Object declared in method &lt;U&gt;mapToObj(IntFunction&lt;? extends U&gt;)
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&lt;Integer&gt; s = stream.flatMap((item)-&gt;new String(item).chars().mapToObj(a-&gt;(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&lt;Character&gt; s = stream.flatMap(item-&gt;{new String(item).chars().mapToObj(a-&gt;(char)a);});

and the issue was missing return statement inside {}. Then I altered the line to

Stream&lt;Integer&gt; s = stream.flatMap((item)-&gt;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&lt;Integer&gt; 替换为 Stream&lt;Character&gt;,因为你在代码中进行了 char 强制转换。

然而,关于你的代码问题在于你不必要地进行了 flatMap 操作Stream.of 需要一个具有引用类型的数组作为其复合类型。此外,Arrays.stream 没有针对 char[] 的重载。你最终会在一个保证只有一个元素的内容上进行流处理。这个元素就是你的 char[]

你可以直接省略 flatMap 操作,直接将 char 数组转换为 String。

String str = new String(arr);
Stream&lt;Character&gt; characterStream = str.chars().mapToObj(c -&gt; (char) c);
英文:

You were almost there. Just replace Stream&lt;Integer&gt; to Stream&lt;Character&gt;, as you are casting to a char in your code.

However, the problem about your code is that you are unnecessarily flatMapping. 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&lt;Character&gt; characterStream = str.chars().mapToObj(c -&gt; (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 = { &#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39; };

new String(arr).chars().forEach(i -&gt; System.out.print(i + &quot; &quot;));

This will print the Unicode numbers. When you want to print characters instead, just change the terminal operation:

new String(arr).chars().forEach(i -&gt; System.out.print((char)i + &quot; &quot;));

or

new String(arr).chars().forEach(i -&gt; System.out.printf(&quot;%c &quot;, i));

You can also use

new String(arr).chars().mapToObj(i -&gt; (char)i).forEach(i -&gt; System.out.print(i+&quot; &quot;));

but this bears boxing overhead, as it creates a Stream&lt;Character&gt;.


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 -&gt; System.out.printf(&quot;%c &quot;, i));

Of course, you can insert as many curlicues as you want, e.g.

Stream.of(arr)
    .flatMapToInt(array -&gt; CharBuffer.wrap(array).chars())
    .mapToObj(i -&gt; (char)i) // returns a Stream&lt;Character&gt; not Stream&lt;Integer&gt;
    .forEach(i -&gt; System.out.printf(&quot;%c &quot;, 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 = {&quot;a&quot;,&quot;b&quot;,&quot;c&quot;,&quot;d&quot;};
Stream.of(stringArray).forEach(System.out::println);

To solve your actual problem, try this.

	 // Creating a character array 
	    char arr[] = { &#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39; }; 

	    // --------- Using Stream.of() --------- 
	    // Will work efficiently 

	    // to convert int array into Stream 
	    Stream&lt;char[]&gt; stream = Stream.of(arr); 
	    

	    // Displaying elements in Stream 
  	    s.forEach(str -&gt; System.out.print(str + &quot; &quot;)); 
	    Stream&lt;Integer&gt; s = stream.flatMapToInt((item)-&gt;(new String(item)).chars()).boxed();
        //or
	    IntStream s = stream.flatMapToInt((item)-&gt;(new String(item)).chars());

	    // Displaying elements in Stream 
	    s.forEach(str -&gt; System.out.print((char)str + &quot; &quot;)); 
  
     
        

</details>



# 答案4
**得分**: 1

以下是翻译好的部分:

你使用了 `Stream&lt;Integer&gt;`,而不是 `Stream&lt;Character&gt;`。如果你想使用 `Stream&lt;Integer&gt;`,你需要使用 [IntStream::boxed][1] 或者像下面展示的那样使用 `mapToObj(a -&gt; 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&lt;char[]&gt; stream1 = Stream.of(arr);
        Stream&lt;Character&gt; chars = stream1.flatMap(item -&gt; new String(item).chars().mapToObj(a -&gt; (char) a));
        chars.forEach(c -&gt; System.out.print(c + " "));

        System.out.println();

        Stream&lt;char[]&gt; stream2 = Stream.of(arr);
        Stream&lt;Integer&gt; ints = stream2.flatMap(item -&gt; new String(item).chars().boxed());
        ints.forEach(i -&gt; System.out.print(i + " "));

        System.out.println();

        Stream&lt;char[]&gt; stream3 = Stream.of(arr);
        Stream&lt;Integer&gt; integers = stream3.flatMap(item -&gt; new String(item).chars().mapToObj(a -&gt; Integer.valueOf(a)));
        integers.forEach(i -&gt; System.out.print(i + " "));
    }
}

输出:

1 2 3 4 5 
49 50 51 52 53 
49 50 51 52 53 
英文:

You have used Stream&lt;Integer&gt; instead of Stream&lt;Character&gt;. If you want to use Stream&lt;Integer&gt;, you need to use IntStream::boxed or mapToObj(a -&gt; Integer.valueOf(a)) as shown below:

import java.util.stream.Stream;

public class Main {
	public static void main(String[] args) {
		char arr[] = { &#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39; };

		Stream&lt;char[]&gt; stream1 = Stream.of(arr);
		Stream&lt;Character&gt; chars = stream1.flatMap(item -&gt; new String(item).chars().mapToObj(a -&gt; (char) a));
		chars.forEach(c -&gt; System.out.print(c + &quot; &quot;));

		System.out.println();

		Stream&lt;char[]&gt; stream2 = Stream.of(arr);
		Stream&lt;Integer&gt; ints = stream2.flatMap(item -&gt; new String(item).chars().boxed());
		ints.forEach(i -&gt; System.out.print(i + &quot; &quot;));

		System.out.println();

		Stream&lt;char[]&gt; stream3 = Stream.of(arr);
		Stream&lt;Integer&gt; integers = stream3.flatMap(item -&gt; new String(item).chars().mapToObj(a -&gt; Integer.valueOf(a)));
		integers.forEach(i -&gt; System.out.print(i + &quot; &quot;));
	}
}

Output:

1 2 3 4 5 
49 50 51 52 53 
49 50 51 52 53 

huangapple
  • 本文由 发表于 2020年5月5日 06:26:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/61602666.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定