栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何转换清单 使用通用方法将数组t [](对于基本类型)设置为?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何转换清单 使用通用方法将数组t [](对于基本类型)设置为?

从当前版本(Java
12)开始,基本类型无法用Java泛型表示。更具体地说,我们不能提供原始类型作为类型参数。(例如,我们不能这样做

Foo<int>
。)我们也不能将类型变量用作
new
表达式中的类型,因此不能
newT[n]
创建数组。因此,没有理想的方法来执行此操作。


可能做到这一点合理的使用一些反射(

java.lang.reflect.Array
),但我们需要提供一个
Class
作为参数。这是一个可能如何完成的示例:

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);int[] ints = toPrimitiveArray(list, int[].class);

请注意,这

Array.set
将执行扩展的原始转换,因此可以进行以下工作:

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;}

但是,有很多问题:

  • 如果列表为空,我们不知道要创建哪种类型的数组。
  • 如果列表中的对象类型不止一种,则无法使用。
  • 未经检查的将结果数组强制转换为
    P
    ,因此存在堆污染的危险。

最好只传入a

Class
作为参数。


另外,虽然可以编写许多重载来取消数组装箱:

public static int[]    unbox(Integer[] arr) {...}public static long[]   unbox(Long[]    arr) {...}public static double[] unbox(Double[]  arr) {...}...

由于类型擦除的影响,不可能编写将许多不同类型的拆箱的重载,

List
如下所示:

public static int[]    unbox(List<Integer> list) {...}public static long[]   unbox(List<Long>    list) {...}public static double[] unbox(List<Double>  list) {...}...

那不会编译,因为在同一个类中,我们不允许有多个具有相同名称和擦除的方法。这些方法必须具有不同的名称。


附带说明一下,这是一些非通用解决方案:

  • 从Java 8中,我们可以拆箱

    List
    Integer
    Long
    Double
    使用
    Stream
    API:

    List<Long> list = List.of(1L, 2L, 3L);

    long[] longs = list.stream().mapToLong(Long::longValue).toArray();

  • Google Guava has

    Collection
    unboxing methods in their
    com.google.common.primitives
    classes, for example
    Doubles.toArray
    :

    List<Double> list = List.of(1.0, 2.0, 3.0);

    double[] doubles = Doubles.toArray(list);



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/516047.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号