想要在java中从char数组创建一个字符流

San*_*Kim 38 java java-8 java-stream

从char数组,我想构建一个流来使用java 8功能,如过滤器和地图.

char[] list = {'a','c','e'};
Stream<Character> cStream = Stream.of(list);
// Stream<Character> cStream = Arrays.stream(list);
Run Code Online (Sandbox Code Playgroud)

第一种方法不起作用(原因:将cStream更改为Stream<char[]>).注释行也不起作用(原因:stream(T[])类型数组中的方法不适用于arguments(char[])).

我知道如果char[] list更改为int[],一切正常使用IntStream.但我不希望每次转换char[]int[]每个时间或更改到一个列表中,当我需要在使用流库char阵列.

Ale*_* C. 31

您可以使用a IntStream生成索引,后跟mapToObj:

char[] arr = {'a','c','e'};
Stream<Character> cStream = IntStream.range(0, arr.length).mapToObj(i -> arr[i]);
Run Code Online (Sandbox Code Playgroud)


Lar*_*sen 20

一种方法是通过String对象:

char[] list = {'a','c','e'};
Stream<Character> charStream = new String(list).chars().mapToObj(i->(char)i);
Run Code Online (Sandbox Code Playgroud)

我喜欢这样做,因为转换数组的所有复杂性都包含在String创建中,并且char的包装也在场景后面执行,因此我可以专注于业务逻辑.

  • 请注意,有时,当您有一个字符数组时,这是因为它是一个敏感值(如密码),并且您明确避免实例化字符串。/sf/ask/621690401/ (3认同)
  • 在语义上与 [this answer](/sf/answers/2215446061/) 没有区别,除了使用 `CharBuffer.wrap(list)` 比使用 `new String(list)` 更有效,因为它没有涉及复制数组,从 Java 9 开始,将字符数组转换为字节数组,并在流式传输时将其转换回来。在 Java 8 下,差异更大,因为 `String.chars()` 的实现很差,而 `CharBuffer.chars()` 的实现很有效。Java 9 已经解决了这个问题,但 `new String(char[])` 的复制/转换开销仍然存在。 (2认同)

Tag*_*eev 16

创建IntStreamfrom char[]数组的一种简短而有效的方法是使用java.nio.CharBuffer:

char[] list = {'a','c','e'};
IntStream stream = CharBuffer.wrap(list).chars();
Run Code Online (Sandbox Code Playgroud)

这样,您可以使用IntStream将int值解释为字符.如果你想要一个盒装Stream<Character>(可能效率较低),请使用

Stream<Character> stream = CharBuffer.wrap(list).chars().mapToObj(ch -> (char)ch);
Run Code Online (Sandbox Code Playgroud)

使用CharBuffer可以比IntStream.range内部自定义spliterator 快一点,因此它不必执行额外的lambda(可能是缓慢的多态调用).它也只引用char[]一次数组而不是lambda内部,所以它可以与非最终数组变量或函数返回值(如CharBuffer.wrap(getCharArrayFromSomewhere()).chars())一起使用.


T.J*_*ika 3

您可以对代码进行的最简单的更改就是更改char[]Character[].

另一种方法是创建一个装箱的新 ArrayList char

char[] list = {'a','c','e'};
List<Character> listArray = new ArrayList<>();
for (char c : list)
    listArray.add(c);
Stream<Character> cStream = listArray.stream();
Run Code Online (Sandbox Code Playgroud)

此外,您可以使用 Google Guava 的Chars类,将for循环替换为:

List<Character> listArray = Chars.asList(list);
Run Code Online (Sandbox Code Playgroud)