java compareTo方法实现

时间:2017-06-04 10:00:56

标签: java comparable compareto

目前我正试图找出java的界面“Comparable”是如何工作的。 据我所知,inteface不能有任何非静态(除了默认的)方法,所以当我们实现一个接口时,我们首先需要定义它的方法。

但是当我实现“Comparable”接口时,我显然可以使用它的compareTo方法。该方法定义在哪里?

public static <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem) {

    int count = 0;

    for (T e : anArray)
        if (e.compareTo(elem) > 0)
            ++count;
    return count;

}

为什么我甚至无法定义界面的方法?

我的apoligies如果已经有一个问题的答案,但是无法找到它。

THX。

2 个答案:

答案 0 :(得分:4)

T[]数组的元素必须是某种实现Comparable<T>的类型(由于<T extends Comparable<T>>类型绑定的结果)。因此,您可以在该数组的元素上调用compareTo()

实现compareTo的位置取决于您传递给方法的数组。例如,如果您传递String[],则会使用compareTo类的String方法。

答案 1 :(得分:0)

致你的代码:

您已在签名中将类型T定义为“可比较”的子类,并且在传入“T”(T [])数组时在参数内使用它。编译器现在知道任何T必须至少是Comparable。

更多信息:

一般情况下,我不建议直接实施Comparable。原因是比较总是在你不知道的背景下。

您应该支持Comparator接口而不是Comparable接口来实现与特定上下文的比较。如果要定义自然顺序,可以将自然比较器作为公共常量。

一些例子:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ComparatorExample {


    public static void main(String[] args) {

        List<SomeObject> list = new ArrayList<>();

        list.add(new SomeObject(1, "dhjf", "A"));
        list.add(new SomeObject(4, "ghdg", "A"));
        list.add(new SomeObject(6, "uztzt", "B"));
        list.add(new SomeObject(1, "jhgf", "C"));
        list.add(new SomeObject(3, "vbbn", "A"));
        list.add(new SomeObject(99, "cvcxc", "A"));
        list.add(new SomeObject(2, "dfdd", "G"));

        // examples

        Collections.sort(list, SomeObject.NATURAL);
        Collections.sort(list, LexicographicOrderByCategoryAndName.INSTANCE); 
        LexicographicOrderByName.INSTANCE.compare(new SomeObject(99, "cvcxc", "A"), new SomeObject(54, "fdjnn", "C"));

    }


    public static class SomeObject {

        public static Comparator<SomeObject> NATURAL = new Comparator<SomeObject>() {

            @Override
            public int compare(SomeObject arg0, SomeObject arg1) {
                return arg1.getId() - arg0.getId();
            }

        };

        private int id;
        private String name;
        private String category;


        public SomeObject(int id, String name, String category) {
            this.id = id;
            this.name = name;
            this.category = category;
        }

        public int getId() {
            return id;
        }

        public String getName() {
            return name;
        }

        public String getCategory() {
            return category;
        }

    }

    public static class LexicographicOrderByName implements Comparator<SomeObject> {

        public static LexicographicOrderByName INSTANCE = new LexicographicOrderByName();

        private LexicographicOrderByName() {
        }

        @Override
        public int compare(SomeObject o1, SomeObject o2) {
            return o1.getName().compareTo(o2.getName());
        }

    }


    public static class LexicographicOrderByCategoryAndName implements Comparator<SomeObject> {

        public static LexicographicOrderByCategoryAndName INSTANCE = new LexicographicOrderByCategoryAndName();

        private LexicographicOrderByCategoryAndName() {
        }

        @Override
        public int compare(SomeObject o1, SomeObject o2) {

            int c = o1.getCategory().compareTo(o2.getCategory());

            if (c == 0) {
                c = o1.getName().compareTo(o2.getName());
            }

            return c;
        }

    }


}

Comparable接口的问题在于,一旦您决定对象的特定比较,您将永远绑定它。你可以改变它但是期望副作用,因为你不知道所有的上下文是否都有相同的擦除,并且也应该改变。