Java:我可以创建通用类型的静态类吗?

时间:2014-11-13 07:10:41

标签: java generics

我正在研究java中的Quicksort算法,我需要使用数组。

现在,我想让这个算法支持排序任何可比较数组。

我环顾四周,但围绕仿制药的大多数讨论和教程都令人困惑。简单地说,我不确定如何使这项工作。我已经确认Quicksort可以与Integers,Strings等一起工作,所以我需要做的就是让它适用于所有可比对象。但我的IDE告诉我,我不能引用非静态类型T"。我不确定这是什么意思。

public class QuickSort<T extends Comparable<T>> {

public static void Sort(T[] A) {
    QuickSortRecursive(A, 0, A.length-1);
}

public static  void QuickSortRecursive(T[] A, int p, int r) {

    if( p < r ) {
        int q = Partition(A, p, r);
        QuickSortRecursive(A, p, q-1);
        QuickSortRecursive(A, q+1, r);
    }
}

public static int Partition(T[] A, int p, int r) {
    String x = A[r];

    int i = p - 1;
    for(int j = p; j < r; j++) {
        if(A[j].compareTo(x) <= 0) {
            i = i + 1;
            //swap A[i] with A[j]
            T tmp = A[i];
            A[i] = A[j];
            A[j] = tmp;
        }
    }
    //swap A[i + 1] with A[r]
    T tmp2 = A[i + 1];
    A[i + 1] = A[r];
    A[r] = tmp2;
    return i + 1;
}

}

简而言之,我在这里做错了什么?

3 个答案:

答案 0 :(得分:2)

哦......好吧......

设计像

这样的通用类时
class QuickSort<T extends Comparable<T>> { ... }

这只是意味着该类的实例可以(并且应该)使用具体的类型参数进行参数化。例如,您可以声明

QuickSort<String> sorter = new QuickSort<>();

静态方法不属于实例,因此这些方法对类型参数T的含义没有任何线索。您可以自己制作这些静态方法:

static <T> void Sort(T[] A) { ... }
static <T> void QuickSortRecursive(T[] A, int p, int r) { ... }
static <T> int Partition(T[] A, int p, int r) { ... }

但这会导致其他一些错误。例如,您的方法Partition中包含以下行:

String x = A[r];

由于参数A的类型为T[],编译器不允许将数组的元素赋值给String类型的变量(T可以是任何东西) 。如果您已经知道,这些是字符串,为什么不简单地声明

static int Partition(String[] A, int p, int r) { ... }

这里不需要仿制药。

此外,OOP是关于对象(又名实例)的,而不是关于静态方法,这是一种更程序化的设计。因此,只需从所有方法中删除 static 关键字,然后将上述问题行更改为

T x = A[r];

然后一切都很好,你可以使用你的课程如下:

QuickSort<String> sorter = new QuickSort<>();
String[] strings = someStrings();
sorter.Sort(strings);

作为旁注:Java代码约定表示方法和变量名称应以较低的字母开头,因此请更好地命名方法sortquickSortRecursivepartition

答案 1 :(得分:1)

您需要在每个方法而不是类上放置泛型类型声明,例如:

public static <T extends Comparable<T>> void sort(T[] A)

答案 2 :(得分:0)

两个问题:

  1. 您正在使用静态方法。任何原因?你什么时候告诉QuickSort T类型是什么? 基本上,您不能在静态方法或静态字段中使用类的泛型类型参数。类类型参数仅在实例方法和实例字段的范围内。
  2. 对于静态字段和静态方法,它们在类的所有实例之间共享,甚至是不同类型参数的实例,因此显然它们不能依赖于特定的类型参数。

    1. 此处的代码:

      public static int Partition(T[] A, int p, int r) {
          String x = A[r];
      
    2. 你的数组是泛型类型(T []),你试图将类型为T的值分配给String?你可能应该这样做

      public static int Partition(T[] A, int p, int r) {
          T x = A[r];