【问题标题】:Java: Passing a comparator to my implementation of qsortJava:将比较器传递给我的 qsort 实现
【发布时间】:2014-01-27 17:31:45
【问题描述】:

我正在编写一种适用于二进制文件的排序方法。 (所有动作都在文件内完成,无需将整个文件读入内存)。

我得到一个: “Comparator 类型中的方法 compare(E, E) 不适用于参数 (so, so)” 来自 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;**

【问题讨论】:

    标签: java generics comparator qsort


    【解决方案1】:

    您真的不应该期望 通用方法 采用 通用比较器 来比较 特定 类型的对象。您的方法具有Comparator&lt;E&gt; 的参数类型,这意味着它可以接受Comparator&lt;T&gt; 的任何参数化实例。您正在对 so 对象调用 compare() 方法。编译器不喜欢这样。如果其他方法将Comparator&lt;Integer&gt; 传递给该方法会发生什么?

    解决问题后,您需要弄清楚,您是否真的需要泛型方法?将参数类型更改为Comparator&lt;so&gt; 不就可以完成您的工作吗?您是否故意创建了泛型方法,或者您不知道它的真正含义?如果是后者,那就不要写泛型方法。因此,只需将所有泛型方法更改为非泛型,并将Comparator&lt;E&gt; 更改为Comparator&lt;so&gt;。这将解决您的问题,而不考虑任何其他问题。

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

    严肃地说:请遵循 Java 命名约定so 作为类名并没有什么意义。取一个合理的名字,让它跟随camel-casing,以大写字母开头。

    【讨论】:

      【解决方案2】:

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

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

      为了让编译器进行类型检查,您应该将 partition 方法的签名更改为:

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

      由此,您可以保证所传递的 Comparator 实例能够处理 so 类型的对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-02
        • 2012-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-09
        • 2016-09-08
        • 1970-01-01
        相关资源
        最近更新 更多