Java 溪流';s限制不适用于基于字符数组的流

Java 溪流';s限制不适用于基于字符数组的流,java,java-8,java-stream,Java,Java 8,Java Stream,为什么下面的代码不将输出限制为仅前三个字符 String vowelOne = "aaebcd"; Stream .of(vowelOne.toCharArray()) .limit(3) .forEach(System.out::println); 输出: aaebcd 我希望输出为: aae Stream.of(char[])生成单个char[]元素的Stream(就像原始数组的Arrays.asList()将生成单个元素的List)

为什么下面的代码不将输出限制为仅前三个字符

 String vowelOne = "aaebcd";

 Stream
    .of(vowelOne.toCharArray())
    .limit(3)       
    .forEach(System.out::println);
输出:

  aaebcd
我希望输出为:

  aae
Stream.of(char[])
生成单个
char[]
元素的
Stream
(就像原始数组的
Arrays.asList()
将生成单个元素的
List
),因此
limit(3)
不会截断
,并且您正在打印整个
char[/code>(即使您使用
println
,也可以从以下事实中看出这一点:所有字符都打印在一行中)

尝试:

输出:

a
a
e

正如Eran提到的,
Stream.of(char[])
将生成一个
流,而不是您需要的
流。有其他方法可以避免这种情况。您需要一个装箱类型的数组
字符[]

static Character[] toCharacterArray(String s) {
    Character[] array = new Character[s.length()];
    for(int i = 0; i < s.length(); i++) {
       array[i] = s.charAt(i);
    }
    return array;
}
或者您可以使用
String.split(“”)创建
String[]

String vowelOne = "aaebcd";

Stream
    .of(vowelOne.split(""))
    .limit(3)
    .forEach(System.out::println);
这两种方法都会导致

a
a
e
一般来说,codePoints()而不是chars()更好,它还可以处理代理项对。我必须承认,这对于你的问题来说可能太过分了

private static String firstN(String input, int limit) {
    StringBuilder builder = new StringBuilder();
    input.codePoints().limit(limit).forEach(builder::appendCodePoint);
    return builder.toString();
}

您刚刚为每个字符创建了一个数组,并将其保存在字符串[]中,然后将数组的数量限制为。这会起作用,但您不认为您只是将它复杂化了,而不是简单地输入一个字符流,它很混乱。@AhmadAlsanie在哪里将每个字符保存在
字符串[]
?元音.split(“”)->将创建字符串[a]、字符串[a]、字符串[e]、字符串[b]、字符串[c]、字符串[d]如果要创建额外的字符数组以获得
,最好使用
IntStream.range(0,arr.length).mapToObj(i->arr[i])。moreStreamOps(…)
直接。如果您确实想要一个
,那么使用
string.chars().mapToObj(i->Character.valueOf((char)i))
将是直接的……请注意,该行为仅仅是一个重载解析的问题,也就是说,您可以通过使用
Stream.of(toCharacterArray(元音)来展示非原始数组的相同行为).limit(3).forEach(System.out::println);
但由于没有专门的
println(Character[])
,因此将使用数组类型的不太富于表现力的
toString()
输出。这里我将使用codePoints()而不是chars()这就引出了一个问题:<代码>限制>代码>。即使代码点不是概念字符,也就是说,你仍然可以在一个由多个代码点组成的字符中间分裂。顺便说一下,“代码”。
已经过时,执行装箱操作只是为了在下一步正确地进行拆箱。@Holger确实如此。我立即想到了具有多个代码点的devanagari字母。对于像法语和瑞典语字母这样的简单情况,需要首先应用规范化,对于devanagari字母,我不知道该怎么说。是的at map是一个错误的复制/粘贴,thx。请注意,您可以使用
collect
使其成为一个更干净的
forEach
更少的解决方案,如图所示。另请参见和
a
a
e
private static String firstN(String input, int limit) {
    StringBuilder builder = new StringBuilder();
    input.codePoints().limit(limit).forEach(builder::appendCodePoint);
    return builder.toString();
}