Java比较器接口和初始化比较器

时间:2015-08-14 20:18:24

标签: java arrays string sorting inheritance

我对Comparator界面有疑问。我的类下面实现了按长度排序字符串的接口,而不是按字符值排序的默认排序。

在覆盖默认比较后,我使用Arrays.sort()对字符串数组进行排序。即使我已经覆盖了默认方法,如果我使用Arrays.sort,它会调用默认的比较而不是我的重写方法。这是因为我明确地调用了超类方法吗?

另一个问题是初始化界面本身。我知道你不能初始化一个接口,而是初始化一个类对象(实现所述接口)来引用接口可用的方法。在这种情况下,当我初始化比较器时,Arrays.sort(strArr, new Ideone());排序正常工作。该方法如何知道我将它传递给比较器?我只初始化了一个类对象,并没有明确地调用compare(ob1, ob2)方法。

即使我做Comparator x = new Ideone();,如何将类对象缩减为比较器对象?对此的任何解释都会有所帮助。

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone implements Comparator
{

    static String ThirdGreatest(String[] strArr)
    { 
        Arrays.sort(strArr);
        //Arrays.sort(strArr, new Ideone());
        for(String x: strArr)
            {
            System.out.println(x);
            }
        return strArr[strArr.length-3];
    } 

    @Override
    public int compare(Object s1, Object s2)
    {
        return (s1.toString().length() - s2.toString().length());
    }

    public static void main (String[] args) throws java.lang.Exception
    {
        String[] myarr = {"coder","byte","code", "asfasfasfasf"};
        System.out.println(ThirdGreatest(myarr));
    }
}

3 个答案:

答案 0 :(得分:5)

  

即使我已经覆盖了默认方法,但如果我使用Arrays.sort,它会调用默认的比较而不是我的重写方法。这是因为我明确地调用了超类方法吗?

不,这是因为在你给出的例子中,你没有通过比较器 - 所以sort方法无法知道你'重新尝试使用自定义比较。

  

在这种情况下,当我初始化比较器时,Arrays.sort(strArr, new Ideone());排序正常工作。该方法如何知道我将它传递给比较器?

因为您正在调用接受比较器的重载。只有 one overload有两个参数:

public static <T> void sort(T[] a, Comparator<? super T> c)

现在可以肯定的是,如果您实施Comparator<String>而不是原始Comparator类型会更好,但它仍然有效。

  

我只是初始化了一个类对象,并没有明确调用compare(ob1, ob2)方法。

确实 - 不必致电compare。这是sort方法的工作。您将比较器传入,以便可以调用compare

答案 1 :(得分:2)

我认为这里的问题是,虽然您已经在Arrays.sort中创建了一个比较器,但实际上并没有让Arrays.sort使用它。默认情况下,如果您只是说

 Arrays.sort(strArr);

然后the strings will be sorted using the default comparator。告诉排序算法使用您的自定义比较器you need to pass it as a second argument to the method:

 Arrays.sort(strArr, new Ideone());

尝试查看是否可以修复问题。作为一个有趣的测试,在比较函数中添加println语句,看看是否可以看到它被调用。

也就是说,用这种方式实现比较器是非常不寻常的。更常见的途径是做这样的事情:

 Arrays.sort(strArr, new Comparator<String>() {
     public int compare(Object s1, Object s2) {
       return (s1.toString().length() - s2.toString().length());
     }
 });

现在,您不需要在compare课程上实施Ideone,这更清楚地表明(1)它不会自动被调用,并且(2)你只需要这个分拣步骤。

答案 2 :(得分:0)

Arrays.sort(strArr)

使用java比较器对字符串对象进行排序。您还没有告诉您的排序功能使用您创建的比较功能。需要引用您的Ideone类。

Comparator x = new Ideone();

因为Ideone()实现了Comparator,所以它必须实现Comparator接口中的所有方法。变量x将在重写时使用Ideone类的compare方法。但是,如果您尝试使用Ideone类中不在Comparator类中的方法,那么您将抛出异常。