Java:将比较器传递给我的qsort实现

时间:2014-01-27 17:31:46

标签: java generics comparator qsort

我正在编写一个适用于二进制文件的排序方法。 (所有操作都在文件内完成而不将WHOLE文件读入内存)。

我得到了: “Comparator类型中的方法比较(E,E)不适用于参数(所以,所以)” 来自qsort方法。

你能明白为什么吗?

谢谢!

代码:

class so {

    // Some object

}

class compareByIntValue implements Comparator<so> {
    public int compare(so o1, so o2) {
        // Comparing
    }
}

class StructureOnFile {

    public static void main(String[] args) throws IOException {

        RandomAccessFile objectsOnFile = new RandomAccessFile(FILENAME, "rw");

        fillWithObjects(objectsOnFile);
        quickSort(objectsOnFile, RecordSize, new compareByIntValue());
.
.
.
        }

    static <E> void quickSort(RandomAccessFile raf,
                              int RecordSize, Comparator<E> c) throws IOException {

        quickSort(raf, RecordSize, c, 0, (int) (raf.length() - RecordSize));

    }

    static <E> void quickSort(RandomAccessFile raf,
                                  int RecordSize, Comparator<E> c, int first, int last) {

        if (last > first) {
            int pivotIndex = partition(raf, RecordSize, first, last, c);
            quickSort(raf, RecordSize, c, first, pivotIndex - RecordSize);
            quickSort(raf, RecordSize, c, pivotIndex + RecordSize, last);
        }

    }

    static <E> int partition(RandomAccessFile list,
                                 int RecordSize, int first, int last, Comparator<E> c) {

        so pivot = new so();
        so tmp = new so();

        list.seek(first);
        pivot.readFromFile(list); // Reads first element into pivot
        int low = first + RecordSize; // Index for forward search
        int high = last; // Index for backward search

        while (high > low) {

            // Search forward from left
            list.seek(low);
            tmp.readFromFile(list);
HERE =================> while (low <= high && c.compare(tmp, pivot) <= 0 )
                low+=RecordSize;**

2 个答案:

答案 0 :(得分:3)

您真的不希望泛型方法使用通用比较器来比较特定类型的对象。您的方法的参数类型为Comparator<E>,这意味着它可以接受Comparator<T>的任何参数化实例。并且您在compare()个对象上调用so方法。编译器不喜欢这样。如果其他方法将Comparator<Integer>传递给方法,会发生什么?

解决了问题后,您需要弄清楚,您是否真的需要通用方法?不只是将参数类型更改为Comparator<so>来完成工作吗?您是否故意创建了通用方法,或者您不知道它的真正含义是什么?如果它是后一个是真的,那么不要写泛型方法。因此,只需将所有通用方法更改为非通用方法,然后将Comparator<E>更改为Comparator<so>。这将解决您的问题,而不是考虑任何其他问题。

另一种方法是避免完全创建Comparator,并使so类实现Comparable<so>,并在那里覆盖并实现compareTo()方法。然后您不需要传递任何Comparator个实例。只需将c.compare(tmp, pivot)替换为tmp.compareTo(pivot)

严肃地说:请遵循 Java命名约定so作为一个班级名称并不是很有道理。给出一些合理的名称,并使其跟随 camel-casing ,从大写字母开始。

答案 1 :(得分:2)

正如Rohit Jain已经注意到的那样:

  

你真的不应该期望使用通用比较器来比较特定类型的对象的通用方法

要使编译器键入check,您应该将 partition 方法的签名更改为:

static int partition(..., Comparator<? super so> c)

通过这种方式,您可以保证传递的Comparator实例能够处理类型类型的对象。