如何正确初始化比较器?

时间:2014-03-02 22:22:36

标签: java string initialization comparator

我需要在MinTester类中编写一个静态方法来计算“最小”字符串 来自使用比较器对象的ArrayList集合:

public static String min(ArrayList<String> list, Comparator<String> comp)

我不能使用Collections类来计算最小值。

这是我到目前为止所拥有的。

public class MinTester 
{
    public static String min(ArrayList<String> list, Comparator<String> comp)
    {
        String shortest = list.get(0);

        for(String str : list) {
            if ( comp.compare(str, shortest) < 0) {
                shortest = str;
            }
        }
        return shortest;
    }
}

我没有从方法中得到任何错误,所以我尝试在Main中测试它。 尝试传递comp时出现此错误:变量comp可能尚未初始化

public static void main(String[] args)
{
    // TODO code application logic here

    MinTester s = new MinTester();
    Comparator<String> comp;
    ArrayList<String> list = new ArrayList<>();

    list.add("a");
    list.add("ab");
    list.add("abc");
    list.add("abcd");

    String a = s.min(list,comp);//Error: Variable comp may not have been initialized

    System.out.println(a);
}

这是我遇到问题的地方。

我试试

Comparator<String> comp = new Comparator<>();//Error:Comparator is abstract, cannot be instantiated
Comparator<String> comp = new MinTester();//Error: MinTester cannot be converted to Comparator<String>

有谁能告诉我处理这个比较器的正确方法?我不确定我是否只是试图错误地初始化它,或者我是否在我的MinTester类中缺少某些内容。

3 个答案:

答案 0 :(得分:5)

您应该为此编写一个实现Comparator<String>的类。使用anonymous class的快速方法:

String a = s.min(list, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return s1.compareTo(s2);
    }
});

由于您需要根据字符串长度进行比较,只需更改compare方法中的比较逻辑:

String a = s.min(list, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return (s1.length() > s2.length()) ? 1 : (s1.length() < s2.length()) ? -1 : 0;
    }
});

如果您碰巧使用Java 7,请使用Integer#compare

String a = s.min(list, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return Integer.compare(s1.length(), s2.length());
    }
});

如果使用Java 8,则可以使用lambda表达式:

String a = s.min(list, (s1, s2) -> Integer.compare(s1.length(), s2.length()));

答案 1 :(得分:1)

Comparator是一个界面;不同的类可以以不同的方式实现它以执行不同类型的比较。您的方法采用Comparator的原因是调用者可以选择如何比较字符串。传入一个词法(也就是字母)比较的Comparator,你将得到词法顺序的第一个字符串。传入查看字符串长度的Comparator,您将获得最短的字符串。

由于String类已经实现了Comparable接口 - 一种允许类定义自己的比较方法的Comparator兄弟 - 这是一个方便的泛型类,可以让你使用任何ComparableComparator界面:

public final class ComparableComparator<T extends Comparable<T>> implements Comparator<T> {
    @Override
    public int compare(final T a, final T b) {
        return a.compareTo(b);
    }
}

将其中一个传递给您的方法,然后使用String类自己的compareTo方法比较字符串。

编辑:在Java 8或更高版本中,Comparator.naturalOrder()方法为您提供相同的功能,因此您无需编写上述类。

答案 2 :(得分:-1)

除非您想要修改字符串比较的自然顺序,否则您不需要使用Comparator,至少不需要使用compareTo()。请改用String类的if (str.compareTo(shortest) < 0) { shortest = str; } 方法。

Comparator

如果您希望修改自然顺序,则可以创建一个实现compare()接口的类,然后将此类的实例传递给public class StringDescComparator implements Comparator<String> { @Override public int compare(String str1, String str2) { // return str1.compareTo(str2); // For natural ordering return -1 * str1.compareTo(str2); // For reversed ordering } } 方法。您还可以为比较定义自己的逻辑。

"b" < "a"

然后,您可以使用上述类的实例按降序进行比较,以便:Comparator comp = new StringDescComparator();

{{1}}