目前我正试图找出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。
答案 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接口的问题在于,一旦您决定对象的特定比较,您将永远绑定它。你可以改变它但是期望副作用,因为你不知道所有的上下文是否都有相同的擦除,并且也应该改变。