【问题标题】:Comparator as a parameter for the constructor of a class比较器作为类的构造函数的参数
【发布时间】:2020-02-08 20:11:47
【问题描述】:

我似乎无法在任何地方找到确切的方法。我正在编写一个将比较器作为类构造函数的参数/参数的类。我想用它来订购列表中的项目。但我不确定如何处理新类中的比较器。

  • 我已经导入java.util.Comparator
  • 在类声明中我说“impements Comparator<T>
  • 我已经写了 (Comparator<T> c) 作为类的构造函数的参数。

我从来没有以这种方式使用过比较器——我将它用作内部类,仅此而已,所以当我将比较器作为构造函数的参数。

我做过的唯一事情就是上面的三个项目符号项。每当我尝试使用作为参数的比较器做某事时,我都会收到一条错误消息。

这是构造函数的代码:

public class SortedList<T> implements Comparator<T>
    //value, position and array are instance variables
    //I am switching array to a List to deal with generics
    private int position;
    private Integer[] array;

    public SortedList(Comparator<T> c){
       this.position = 0;
       this.array = new Integer[25];
    }

    public void sort(Integer num){
       boolean valid = false;
       int i = 0;

       while(!valid && i < array.length-1){
          if(num.compareTo(array[i] > 0)){
            array[i+1] = array[i];
            array[i] = num;
          }else{
            i++;
       }
    }

我收到的错误消息是:

  • 找不到符号 - 方法 compareTo

我希望能够比较任意两个对象,而不仅仅是整数,这就是我想将比较器作为参数的原因。

【问题讨论】:

  • 你能分享你的代码吗? TreeMap 有一些构造函数需要 Comparator 作为参数 (OpenJDK 11 sources of TreeMap)
  • 传递的参数只是一个实现Comparator的实例,它可以像Comparator的任何其他实例一样传递给Collections.sort
  • 如果为构造函数提供了Comparator,那么您就不需要implements 比较器 - 只需使用它 - 但您没有显示可以使用它的代码,这样会有所帮助 -如果出现错误,请显示错误。
  • 我刚刚添加了代码——抱歉花了这么长时间,我没有充实排序方法,因为我无法让比较器工作。
  • 错误是找不到比较方法。我认为问题在于我不知道在这种情况下如何使用比较器。我无法创建比较器的实例(这是另一个错误消息)。我什至如何使它工作,以便我可以比较两个对象?理论上,我会比较其他类型的对象(这就是我想将比较器作为参数的原因),而不仅仅是整数,我只是用它来测试它。

标签: java comparator comparable


【解决方案1】:

您的问题尚不清楚,但您的 sn-p 中唯一的集合结构是整数对象数组。因此,这里唯一合理的排序就是那个数组。

您需要Comparator&lt;Integer&gt; 来排序,而不是Comparator&lt;T&gt;

一旦你有了它,要对该数组进行排序,你需要做的就是......

Arrays.sort(array, c);

【讨论】:

  • 对,我一直在修补它,试图让它与非泛型(如整数)一起工作,但是,我的真正目标是比较数组中的泛型,但我不记得如何创建一个泛型数组——这就是为什么我在这部分切换到 Integer。
  • 我还想在项目进入数组之前对其进行比较,这就是我不使用 arrays.sort 的原因。
  • 你不能有一个泛型数组。你可以有一个List&lt;T&gt;。您可以对它们进行相同的排序。如果您必须使用数组,则必须解决一些泛型问题(这涉及获得一些警告,然后您必须禁止这些警告,以及一些强制转换);示例参见 ArrayList.java 的源代码。
  • 感谢您清理这部分内容!我将切换到列表(我知道使用泛型和基于错误的数组肯定有问题)......但是我怎样才能比较像这样的两个对象:object1.compareTo(object2)和我接受的比较器作为一个参数?假设我切换到可以采用泛型的列表。
  • comparator.compare(o1, o2)
【解决方案2】:

您的SortedList&lt;T&gt; 类不得实现Comparator&lt;T&gt; 接口,因为该类不用于比较对象。但是,它将使用给定的Comparator&lt;T&gt; 实例对其条目进行排序。这意味着类和方法应具有以下定义:

public class SortedList<T> {
     // ...
}

该类不再实现Comparator&lt;T&gt; 接口。

private T[] array;

array 字段应为 T[] 类型,因为此 SortedList&lt;T&gt; 对象用于排序/保存 T 类型的对象,而不是 Integer 对象。

public SortedList(Comparator<T> c){
    // ...
    this.comparator = c;
}

没错。构造函数接收一个Comparator&lt;T&gt; 实例。您应该将此引用存储到一个字段,以便以后在您的 sort() 方法中使用它。

public void sort(){
    // ...
}

sort() 方法上的 Integer 参数没有任何意义,因此请将其删除。现在您可以在您的sort() 方法中使用存储的Comparator&lt;T&gt; 实例并调用其compare() 方法来比较存储数组中的两个对象。代码片段可能如下所示:

// ...
if (this.comparator.compare(this.array[i], this.array[i+1])) {
    // it should be on the left
} else {
    // it should be on the right
}
// ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多