簡體   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