Java 如何正确初始化比较器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22134406/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 13:49:41  来源:igfitidea点击:

How to correctly initialize a Comparator?

javastringinitializationcomparator

提问by Reeggiie

I need to write a static method in a class MinTester that computes the "smallest" string from an ArrayList collection using a comparator object:

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

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

I cannot use the Collections class to compute the minimum.

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

Here is what I have so far.

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

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;
    }
}

I am not getting any errors here from the method, So I try to test it in Main with this. I get this error when trying to pass comp: Variable comp may not have been initialized

我没有从该方法中得到任何错误,因此我尝试在 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);
}

Heres where I run into my problem.

这是我遇到问题的地方。

I try

我试试

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>

Can anyone tell me the proper way to handle this Comparator? Im not sure if Im just trying to initialize it incorrectly, or if I'm missing something in my MinTester class.

谁能告诉我处理这个比较器的正确方法?我不确定我是否只是试图错误地初始化它,或者我是否在 MinTester 类中遗漏了一些东西。

采纳答案by Luiggi Mendoza

You should write a class that implements Comparator<String>for this. A quick approach using anonymous class:

您应该编写一个实现Comparator<String>此功能的类。使用匿名类的快速方法:

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

Since you need to compare based on String length, just change the comparison logic in the comparemethod:

由于需要根据String长度进行比较,只需在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;
    }
});

If you happen to use Java 7, then use Integer#compare:

如果您碰巧使用 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());
    }
});

If you use Java 8, you can use a lambda expression:

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

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

回答by Kedarnath Calangutkar

You do not need to use Comparator, at least not unless you want to modify the natural ordering of the string comparisons. Use the compareTo()method for the Stringclass instead.

您不需要使用Comparator,至少不需要,除非您想修改字符串比较的自然顺序。请改用该类的compareTo()方法String

if (str.compareTo(shortest) < 0) {
     shortest = str;
}

If at all you wish to modify the natural ordering, you can create a class which implements the Comparatorinterface and then pass an instance of this class to the compare()method. You can also define your own logic for the comparisons.

如果您希望修改自然顺序,您可以创建一个实现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
    }
}

Then you can use an instance of the above class to compare in the descending order such that: "b" < "a"

然后,您可以使用上述类的实例按降序进行比较,例如: "b" < "a"

Comparator comp = new StringDescComparator();

回答by Wyzard

Comparatoris an interface; different classes can implement it in different ways to perform different kinds of comparisons. The reason why your method takes a Comparatoris so that the caller can choose how the strings should be compared. Pass in a Comparatorthat does lexical (aka alphabetical) comparison, and you'll get the first string in lexical order. Pass in a Comparatorthat looks at string length, and you'll get the shortest string.

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

Since the Stringclass already implements the Comparableinterface — a sort of sibling to Comparatorthat lets a class define its own comparison method — here's a handy generic class that lets you use any Comparablethrough the Comparatorinterface:

由于String该类已经实现了Comparable接口——一种Comparator允许类定义自己的比较方法的兄弟——这里有一个方便的泛型类,它可以让你Comparable通过Comparator接口使用 any :

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);
    }
}

Pass one of those into your method and it'll compare the strings using the Stringclass's own compareTomethod.

将其中之一传递到您的方法中,它将使用String类自己的compareTo方法比较字符串。

Edit:In Java 8 or later, the Comparator.naturalOrder()method gives you the same thing, so you don't need to write the class above.

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