Java 如何转换列表<;T>;是否使用泛型方法数组t[](对于基元类型)?

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和convertShortListToArray)转换为一个(convertListToArray):

公共类助手{
公共静态浮点[]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);