Java中如何不使用System.arraycopy将List<char[]>转为char[]数组
Java 8 下将
List<char[]>扁平化为char[]的无装箱实现 Java 8标准库没有提供原生char类型的专用Stream(类似IntStream/LongStream的原生流实现),因此无法直接通过对象流的flatMap一步得到原生char数组,但可以通过以下两种方式实现,完全不需要将char装箱为Character包装类型,避免不必要的性能开销。
方式1:基于IntStream+StringBuilder实现(代码最简洁)
利用CharBuffer.wrap(char[]).chars()返回的原生IntStream承载char值(char本质是16位无符号整数,可以安全用int存储),全程无包装类装箱,代码简洁易读,适合绝大多数业务场景:
import java.nio.CharBuffer; import java.util.List; // 输入示例 List<char[]> listOfCharArrays = /* 你的输入列表 */; char[] result = listOfCharArrays.stream() // 将每个char[]转为原生IntStream,元素为char对应的int值,无装箱 .flatMapToInt(arr -> CharBuffer.wrap(arr).chars()) // 用StringBuilder收集字符,全程操作原生类型 .collect( StringBuilder::new, (sb, charVal) -> sb.append((char) charVal), StringBuilder::append ) .toString() .toCharArray();
方式2:预计算长度+数组拷贝(性能最优)
如果追求极致性能,避免StringBuilder中转的额外开销,可以先通过Stream计算所有字符数组的总长度,一次性分配目标数组后通过System.arraycopy批量拷贝,是所有实现中效率最高的方案:
import java.util.List; List<char[]> listOfCharArrays = /* 你的输入列表 */; // 先通过Stream计算总字符长度 int totalLen = listOfCharArrays.stream() .mapToInt(arr -> arr.length) .sum(); // 分配目标数组,批量拷贝内容 char[] result = new char[totalLen]; int offset = 0; for (char[] arr : listOfCharArrays) { System.arraycopy(arr, 0, result, offset, arr.length); offset += arr.length; }
注意:你给出的示例代码实际存在编译错误:
Stream.of(listOfCharArrays).flatMap(List::stream)执行后得到的是Stream<char[]>,而非Stream<Character>,如果要按该逻辑收集为Character[],必须额外拆分数组并将每个原生char装箱为Character对象,会产生大量不必要的包装类对象,性能差,不推荐使用。
内容的提问来源于stack exchange,提问作者rmf
相关产品推荐
相关产品推荐

