【问题标题】:java compareTo method implementationjava compareTo方法的实现
【发布时间】:2017-06-04 10:00:56
【问题描述】:

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

但是当我实现“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;

}

我怎么不用定义接口的方法就可以使用呢?

如果该问题已经有答案,我表示歉意,但无法找到。

谢谢。

【问题讨论】:

  • anArray的对象类中定义。

标签: java comparable compareto


【解决方案1】:

T[] 数组的元素必须是实现Comparable&lt;T&gt; 的某种类型(作为&lt;T extends Comparable&lt;T&gt;&gt; 类型绑定的结果)。因此,您可以在该数组的元素上调用 compareTo()

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

【讨论】:

    【解决方案2】:

    到你的代码:

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

    更多信息:

    一般我不建议直接实现 Comparable。原因是比较总是在你不知道的环境中进行。

    您应该优先使用 Comparator-interface 而不是 Comparable-interface 来实现与特定上下文的比较。如果你想定义一个自然顺序,你可以提供一个自然比较器作为公共常量。

    一些例子:

    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-interface 的问题在于,一旦你决定对一个对象进行特定的比较,你就会永远绑定到它。您可以更改它,但会产生副作用,因为您不知道是否所有上下文都具有相同的擦除并且也应该更改。

    【讨论】:

      最近更新 更多