我正在尝试将 String 转换为Stream<Character>
,并遇到了这种奇怪的事情。
似乎word.toCharArray()
返回了一个 Array ,但是当我尝试通过Arrays.asList(word.toCharArray())
将其转换为列表时,它似乎失败了(输出是一个完整的 > String )。
这是怎么回事?
@Test
public void testCharacterStream() {
characterStreamNew("HELLO");
}
private Stream<Character> characterStreamNew(String word) {
for(Character c: word.toCharArray()) {
out.println(c);
}
Arrays.asList(word.toCharArray()).stream()
.peek(out::println)
.forEachOrdered(out::println);
return null;
}
这是输出:
H
E
L
L
O
HELLO
HELLO
答案 0 :(得分:5)
这是怎么回事?
这是Arrays.asList
的签名:
public static <T> List<T> asList(T... a)
首先发现T
必须是引用类型。所有Java类型参数都是引用类型。
第二个观察结果是a
是一个varargs参数。这意味着a
可以表示为一个或多个T
实例……也可以表示为T[]
。
以您的示例为例。看来您希望下面的表达式产生char
或Character
的列表。
Arrays.asList(word.toCharArray())
首先,List<char>
不是有效的Java类型,因为char
不是引用类型。
第二,无法生成List<Character>
,因为签名不允许这样做。咱们试试吧。如果T
为Character
,则替换为
public static List<Character> asList(Character... a)
但是Character
实际上是指Character[]
,而word.toCharArray()
会产生char[]
。 (并且Java语言不会将char[]
转换为Character[]
。)
实际上,实际上发生的是T
与char[]
匹配,并且Arrays.asList
的结果将是List<char[]>
。而您得到的对象将是一个大小为1的列表,其中包含单个char[]
元素,其中包含word
的所有字符。
答案 1 :(得分:4)
您可以像这样使用chars()
:
word.chars()
.mapToObj(c -> (char) c)
.forEachOrdered(System.out::println);
输出
H
E
L
L
O
您的方法如下所示:
private static Stream<Character> characterStreamNew(String word) {
return word.chars().mapToObj(c -> (char) c);
}
答案 2 :(得分:3)
String.toCharArray()
返回一个对象:String
的数组。
因此,您在此处流式传输List
,其中包含单个元素:代码中的字符串数组
Arrays.asList(word.toCharArray()).stream()
.peek(out::println)
.forEachOrdered(out::println);
您得到的结果。
因此,您应该尝试另一种方式来实现所需的功能。
实际上,没有直接方法来获得Stream
中的Character
,因为它不存在。最接近的单个事物是IntStream
,它可以处理int
的流,但也可以处理short
的流或char
的流。
根据YCF_L的建议,您可以使用String.chars()
返回IntStream
或返回String.codePoints()
。
char的整数表示形式不适合人类阅读,因此需要使用int
将char
元素强制转换为mapToObj()
。