繁体   English   中英

泛型类型函数的返回语句出错

[英]Error with return-statement of generic type function

我试图制作一个通用函数,将一个数组(int [],String [])传递给该函数,并使用TreeSort返回它的排序版本。 因为主类拒绝接受int []数组作为参数 ,所以我什至没有机会对其进行调试。

TreeSort

public T[] treeSort(T[] arr) {

  T[] result = (T[]) new Object[arr.length];

  for (int i = 0; i < arr.length; i++)
    if (arr[i] != null) 
      add(arr[i]);

  Iterator it = iterator();
  int count = 0;
  while (it.hasNext()) 
    result[count++] = (T) it.next();

  return (T[]) result;
}

主要

BinarySearchTree<Integer> tree2 = new BinarySearchTree<>();
int[] unsortedNums = {6,3,7,4,1,2,9,8,5};
int[] sortedNums   = tree2.treeSort(unsortedNums);

错误

BinarySearchTree类型的方法treeSort(Integer [])不适用于参数(int [])

因此,我尝试将unsortedNumssortedNumsint更改为Integer (为什么sortedNums ?),现在运行它会产生此错误:

错误2

线程“主”中的异常java.lang.ClassCastException:[Ljava.lang.Object; 无法转换为[Ljava.lang.Comparable;

在线

T[] result = (T[]) new Object[arr.length];

在Java的通用方法中,不允许创建通用类型的数组。 您正在尝试通过创建一个Object数组并将其强制转换为通用类型来规避此规则,但是编译器太聪明了,因此无法这样做。 该规则的原因在于,泛型类型很可能是接口,因此运行时不知道要创建哪个类。

以您的示例为例,如果您确实需要按原样保留未排序的数组并返回一个副本(通常,排序发生在原位,因此您只需编辑原始数组),则可以让用户传递通用类型(如sp00m的回答),或者让用户提供目标数组作为参数,因此您无需自己创建数组。

IMO,这里的最佳实践是使您的排序发生在适当的位置,而不是返回数据的排序后的副本。

代替:

T[] result = (T[]) new Object[arr.length];

您必须使用:

T[] result = (T[]) Array.newInstance(clazz, arr.length);

其中clazz是嵌套元素的类型:

public T[] treeSort(T[] arr, Class<T> clazz) {...}

最后,在调用时,使用装箱的原语:

Integer[] unsortedNums = { 6, 3, 7, 4, 1, 2, 9, 8, 5 };
Integer[] sortedNums = treeSort(unsortedNums, Integer.class);

在Java中,数组在运行时知道其组件类型(组件类型是实际运行时数组类型的一部分),因此您需要在运行时指定组件类型以创建该类型的数组。

@spoom的答案向您展示了如何在传递给函数的类对象下创建数组。 但是,您实际上已经拥有该信息,而没有单独传递它。 参数arrT[]类型,这意味着数组对象的实际运行时类型必须为T[]或其子类。 我们可以从中提取组件类型并使用它来创建新的数组:

T[] result = (T[]) Array.newInstance(arr.getClass().getComponentType(), arr.length);

例如,这就是Arrays.copyOf()和相关函数的工作方式。

您不能在泛型中使用基本类型(int)。 例如,尝试使用对象包装器

Integer[] unsortedNums = {6,3,7,4,1,2,9,8,5}; Integer[] sortedNums = tree2.treeSort(unsortedNums);

在Java中,将泛型和数组结合起来是有问题的。 查看文章通用限制

对于解决问题,最简单的方法不是使用数组,而是使用列表。 因此,例如:

public List<T> treeSort(List<T> list) {

    List<T> result = new ArrayList<T>(list.size());

    for (int i = 0; i < list.size(); i++)
        if (list.get(i) != null)
            result.add(list.get(i));

    Iterator<T> it = list.iterator();
    int count = 0;
    while (it.hasNext())
        result.set(count++, it.next());

    return result;
}

提醒您,我尚未测试逻辑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM