如何将 Collection<char[]> 转换为 java 中的 char[][]?
How can I convert Collection<char[]> to char[][] in java?
我正在尝试加速算法的现有实现,以便在 GPU 上对其进行并行化,但为此我需要将所有数据类型转换为原语。
我有一个字符数组集合 Collection<char[]>
我怎样才能将它转换成一个字符数组数组 char[][]
?
我试过了final char[][] kernelFeatures = (char[][]) features.toArray();
但是,我收到一条错误消息 java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [[C ([Ljava.lang.Object; and [[C are in module java.base of loader 'bootstrap')
。
试试这个:
List<char[]> list = List.of(new char[] { '1', '2'
}, new char[] { '3', '4'
}, new char[] { '6', '7'
});
char[][] array = list.stream().toArray(char[][]::new);
System.out.println(Arrays.deepToString(array));
或者用 for 循环打印出来
for (char[] c : array) {
System.out.println(Arrays.toString(c));
}
问题
您不能使用 Collection#toArray()
并将结果转换为 char[][]
的原因是:
The returned array's runtime component type is Object
.
解决方案
前 Java 11
您可以使用 Collection#toArray(T[])
来指定数组的组件类型。
Collection<char[]> collection = ...;
char[][] array = collection.toArray(new char[0][]);
要理解为什么不需要指定第二维,请记住 Java 中的二维数组只是一维数组,其中每个元素都是一个数组。有关详细信息,请参阅这些问答:
- Syntax for creating a two-dimensional array
- Why second dimension is not mandatory in 2d array in java?
关于使用0
作为第一个维度,注意不需要使用0
;您可以使用您想要的任何有效长度(例如 collection.size()
)。然而,使用 0
的原因是它据说更有效,至少在 HotSpot 8 上使用 ArrayList
时是这样:
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
我不确定它在其他版本、其他 JVM 实现或其他 Collection
实现中是否更有效。
Java11+
如果您使用的是 Java 11+,那么有一个 替代 解决方案:Collection#toArray(IntFunction)
.
Collection<char[]> collection = ...;
char[][] array = collection.toArray(char[][]::new);
作为 lambda 表达式,它看起来像:
Collection<char[] collection = ...;
char[][] array = collection.toArray(i -> new char[i][]);
手动复制
这两种 #toArray
方法最终都会做类似的事情:
Collection<char[]> collection = ...;
char[][] array = new char[collection.size()][];
int index = 0;
for (char[] element : collection) {
array[index++] = element;
}
虽然您应该使用 #toArray
方法之一,因为它允许 Collection
实现使用它可以使用的任何优化。例如ArrayList
class使用System#arraycopy
方法。
我正在尝试加速算法的现有实现,以便在 GPU 上对其进行并行化,但为此我需要将所有数据类型转换为原语。
我有一个字符数组集合 Collection<char[]>
我怎样才能将它转换成一个字符数组数组 char[][]
?
我试过了final char[][] kernelFeatures = (char[][]) features.toArray();
但是,我收到一条错误消息 java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [[C ([Ljava.lang.Object; and [[C are in module java.base of loader 'bootstrap')
。
试试这个:
List<char[]> list = List.of(new char[] { '1', '2'
}, new char[] { '3', '4'
}, new char[] { '6', '7'
});
char[][] array = list.stream().toArray(char[][]::new);
System.out.println(Arrays.deepToString(array));
或者用 for 循环打印出来
for (char[] c : array) {
System.out.println(Arrays.toString(c));
}
问题
您不能使用 Collection#toArray()
并将结果转换为 char[][]
的原因是:
The returned array's runtime component type is
Object
.
解决方案
前 Java 11
您可以使用 Collection#toArray(T[])
来指定数组的组件类型。
Collection<char[]> collection = ...;
char[][] array = collection.toArray(new char[0][]);
要理解为什么不需要指定第二维,请记住 Java 中的二维数组只是一维数组,其中每个元素都是一个数组。有关详细信息,请参阅这些问答:
- Syntax for creating a two-dimensional array
- Why second dimension is not mandatory in 2d array in java?
关于使用0
作为第一个维度,注意不需要使用0
;您可以使用您想要的任何有效长度(例如 collection.size()
)。然而,使用 0
的原因是它据说更有效,至少在 HotSpot 8 上使用 ArrayList
时是这样:
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
我不确定它在其他版本、其他 JVM 实现或其他 Collection
实现中是否更有效。
Java11+
如果您使用的是 Java 11+,那么有一个 替代 解决方案:Collection#toArray(IntFunction)
.
Collection<char[]> collection = ...;
char[][] array = collection.toArray(char[][]::new);
作为 lambda 表达式,它看起来像:
Collection<char[] collection = ...;
char[][] array = collection.toArray(i -> new char[i][]);
手动复制
这两种 #toArray
方法最终都会做类似的事情:
Collection<char[]> collection = ...;
char[][] array = new char[collection.size()][];
int index = 0;
for (char[] element : collection) {
array[index++] = element;
}
虽然您应该使用 #toArray
方法之一,因为它允许 Collection
实现使用它可以使用的任何优化。例如ArrayList
class使用System#arraycopy
方法。