Java 里如何把一个 List简捷地处理成 int[][]
问题后附解析,感谢 @_TNT_ 的启示
如题:Java 里如何把一个 List<int[]>
简捷地处理成 int[][]
。
排除下面使用循环一个个赋值的写法(以及 arraycopy
)
package jamesfan.playground.java;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public final class App {
private App() {
}
public static void main(String[] args) {
List<int[]> source = Stream
.of(
new int[] { 1, 2, 3, 4 },
new int[] { 11, 12, 13 },
new int[] { 11, 22, 33, 44, 55 }
)
.collect(Collectors.toList());
// !!! 这句话会报错,貌似 int[][] 并不是 int[] 的数组
// int[][] target = (int[][]) source.stream().toArray();
int[][] target = new int[3][];
IntStream.range(0, source.size())
.forEach(i -> {
target[i] = source.get(i);
});
// arraycopy 和上面的循环是一个道理,排除此解法
// int[][] target = new int[source.size()][];
// System.arraycopy(source.toArray(), 0, target, 0, source.size());
Arrays.stream(target)
.forEach(line -> {
Arrays.stream(line).forEach(n -> System.out.printf("%5d", n));
System.out.println();
});
}
}
int[][]
在 Java 中是一个二维数组,int[]
是一个对象,理论上来说应该可以声明一个 int[]
数组,也就是整数数组的数组……这东西又该怎么声明?
最近一直在写 C# 和 JavaScript 的代码,突然在 Java 中遇到这个问题,感到困惑。难道 Java 栈的同学一直喜欢用 List 是跟这有关系?
遇到这个问题的时候,可能是魔怔了, 一直在纠结为什么 (int[][]) source.stream().toArray()
这句类型转换不对。在 @_TNT_ 答案的启示下,终于想明白了:
Java 的泛型参数是一般可以认为是编译期类型,运行时是被擦除掉的(也有保留的情况,这里不讨论,参阅此文)。
因此,我一开始想当然的认为 Stream.toArray()
会返回 int[][]
是错误的想法。虽然接口提示是 Object[]
,但我想当然地认为只是接口类型声明为 Object[]
实际类型是 int[][]
,完全没想到 toArray()
内部根本拿不到类型信息 —— 直到看到 toArray(new int[0][])
,才醒悟需要通过参数带入实际类型。Stream.toArray
有两个重载
Object[] toArray()
A[] toArray(IntFunction<A[]> generator)
很显然这里应该用第 2 个,也就是
int[][] target = source.stream().toArray(int[][]::new);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
后面的数组初始化大小写
0
算是一种通用写法,在ArrayList
的时候效率更高如果确定不是
ArrayList
的话可以指定成需要的大小