Java 如何转换列表<;T>;是否使用泛型方法数组t[](对于基元类型)?
我正在使用泛型方法进行一些测试,我想将下面两个方法(convertFloatListToArray和convertShortListToArray)转换为一个(convertListToArray):Java 如何转换列表<;T>;是否使用泛型方法数组t[](对于基元类型)?,java,arrays,generics,collections,generic-method,Java,Arrays,Generics,Collections,Generic Method,我正在使用泛型方法进行一些测试,我想将下面两个方法(convertFloatListToArray和convertShortListToArray)转换为一个(convertListToArray): 公共类助手{ 公共静态浮点[]convertFloatListToArray(列表){ float[]数组=新的float[list.size()]; 对于(int i=0;i,在当前版本(Java 12)中,基元类型不能用Java泛型表示。更具体地说,我们不能提供基元类型作为类型参数。(我们不能
公共类助手{
公共静态浮点[]convertFloatListToArray(列表){
float[]数组=新的float[list.size()];
对于(int i=0;i,在当前版本(Java 12)中,基元类型不能用Java泛型表示。更具体地说,我们不能提供基元类型作为类型参数。(我们不能这样做,例如Foo
)我们也不能在new
表达式中使用类型变量作为类型,因此我们不能执行new t[n]
创建数组。因此,没有理想的方法
使用一些反射()可以合理地做到这一点,但我们需要提供一个类作为参数。下面是一个如何做到这一点的示例:
/**
* Unboxes a List in to a primitive array.
*
* @param list the List to convert to a primitive array
* @param arrayType the primitive array type to convert to
* @param <P> the primitive array type to convert to
* @return an array of P with the elements of the specified List
* @throws NullPointerException
* if either of the arguments are null, or if any of the elements
* of the List are null
* @throws IllegalArgumentException
* if the specified Class does not represent an array type, if
* the component type of the specified Class is not a primitive
* type, or if the elements of the specified List can not be
* stored in an array of type P
*/
public static <P> P toPrimitiveArray(List<?> list, Class<P> arrayType) {
if (!arrayType.isArray()) {
throw new IllegalArgumentException(arrayType.toString());
}
Class<?> primitiveType = arrayType.getComponentType();
if (!primitiveType.isPrimitive()) {
throw new IllegalArgumentException(primitiveType.toString());
}
P array = arrayType.cast(Array.newInstance(primitiveType, list.size()));
for (int i = 0; i < list.size(); i++) {
Array.set(array, i, list.get(i));
}
return array;
}
但它不会执行缩小转换,因此下面抛出一个异常:
List<Integer> list = List.of(1, 2, 3);
byte[] bytes = toPrimitiveArray(list, byte[].class); // throws
由于的影响,不可能编写重载来取消装箱许多不同类型的列表
,如下所示:
public static int[] unbox(List<Integer> list) {...}
public static long[] unbox(List<Long> list) {...}
public static double[] unbox(List<Double> list) {...}
...
Google Guava在其类中有Collection
unboxing方法,例如:
List List=List.of(1.0,2.0,3.0);
double[]doubles=doubles.toArray(列表);
简短回答:Java基本类型在对象类型系统下是不统一的/不可统一的。这个问题的可能重复似乎不是该问题的好重复。OP的代码演示了如何获取float[]
,Short[]
数组来自相应的列表
,列表
列表。这与列表
->浮点[]
不同。(我不知道为什么会有反对票;例如,我希望在C#/.NET中也能做到这一点。这就保证了对Java通用实现的讨论,或者至少是一个相关的副本。)@PauloLeite:简单的回答是,如果不将类
传递给该方法,则无法执行该操作。@user2864740但short[]或float[]不是基元类型。
List<Integer> list = List.of(1, 2, 3);
int[] ints = toPrimitiveArray(list, int[].class);
List<Integer> list = List.of(1, 2, 3);
double[] doubles = toPrimitiveArray(list, double[].class);
List<Integer> list = List.of(1, 2, 3);
byte[] bytes = toPrimitiveArray(list, byte[].class); // throws
public static int[] toIntArray(List<Integer> list) {
return toPrimitiveArray(list, int[].class);
}
public static double[] toDoubleArray(List<Double> list) {
return toPrimitiveArray(list, double[].class);
}
...
public static <P> P toPrimitiveArray(List<?> list) {
Object obj0 = list.get(0);
Class<?> type;
// "unbox" the Class of obj0
if (obj0 instanceof Integer)
type = int.class;
else if (obj0 instanceof Double)
type = double.class;
else if (...)
type = ...;
else
throw new IllegalArgumentException();
Object array = Array.newInstance(type, list.size());
for (int i = 0; i < list.size(); i++) {
Array.set(array, i, list.get(i));
}
return (P) array;
}
public static int[] unbox(Integer[] arr) {...}
public static long[] unbox(Long[] arr) {...}
public static double[] unbox(Double[] arr) {...}
...
public static int[] unbox(List<Integer> list) {...}
public static long[] unbox(List<Long> list) {...}
public static double[] unbox(List<Double> list) {...}
...
List<Long> list = List.of(1L, 2L, 3L);
long[] longs = list.stream().mapToLong(Long::longValue).toArray();
List<Double> list = List.of(1.0, 2.0, 3.0);
double[] doubles = Doubles.toArray(list);