为什么一个Java类实现可比较?
为什么使用Java Comparable
? 为什么有人会在课堂上实现Comparable
? 什么是您需要实施可比较的真实生活的例子?
这是一个真实的生活样本。 请注意, String
也实现了Comparable
。
class Author implements Comparable<Author>{ String firstName; String lastName; @Override public int compareTo(Author other){ // compareTo should return < 0 if this is supposed to be // less than other, > 0 if this is supposed to be greater than // other and 0 if they are supposed to be equal int last = this.lastName.compareTo(other.lastName); return last == 0 ? this.firstName.compareTo(other.firstName) : last; } }
后来..
/** * List the authors. Sort them by name so it will look good. */ public List<Author> listAuthors(){ List<Author> authors = readAuthorsFromFileOrSomething(); Collections.sort(authors); return authors; } /** * List unique authors. Sort them by name so it will look good. */ public SortedSet<Author> listUniqueAuthors(){ List<Author> authors = readAuthorsFromFileOrSomething(); return new TreeSet<Author>(authors); }
可比较定义了一个自然排序。 这意味着,当一个对象被认为是“小于”或“大于”时,就是在定义它。
假设你有一堆整数,你想对它们进行排序。 这很容易,只要把它们放在一个排序的集合中,对吧?
TreeSet<Integer> m = new TreeSet<Integer>(); m.add(1); m.add(3); m.add(2); for (Integer i : m) ... // values will be sorted
但是现在假设我有一些自定义的对象,排序对我来说是有意义的,但是没有定义。 比方说,我用有人口密度的邮政编码代表地区的数据,我想按密度对它们进行排序:
public class District { String zipcode; Double populationDensity; }
现在,对它们进行排序的最简单的方法是通过实现Comparable以自然顺序来定义它们,这意味着这些对象被定义为一种标准的方式来排序:
public class District implements Comparable<District>{ String zipcode; Double populationDensity; public int compareTo(District other) { return populationDensity.compareTo(other.populationDensity); } }
请注意,您可以通过定义比较器来做同样的事情。 区别在于比较器定义了对象之外的排序逻辑。 也许在一个单独的过程中,我需要通过zipcode命令相同的对象 – 在这种情况下,排序不一定是对象的属性,或不同于对象的自然排序。 您可以使用外部比较器来定义整数的自定义排序,例如按字母顺序排序。
基本上排序逻辑必须存在的地方。 那可以 –
-
在对象本身中,如果它是自然可比较的(扩展可比较的整数)
-
如上例所示,由外部比较器提供。
从javadoc引用;
这个接口对每个实现它的类的对象进行了总排序。 这个顺序被称为类的自然顺序,类的compareTo方法被称为自然比较方法。
实现此接口的对象的列表(和数组)可以通过Collections.sort(和Arrays.sort)自动排序。 实现此接口的对象可以用作有序映射中的键或排序集中的元素,而无需指定比较器。
编辑:..使重要的位大胆。
一个类实现Comparable
的事实意味着你可以从这个类中取出两个对象并进行比较。 有些类,像某些集合(集合中的排序函数),依赖于它们的可比性(为了排序,您需要知道哪个对象是“最大的”等等)。
上面的大多数示例演示了如何重用compareTo函数中的现有可比对象。 如果您想要比较同一类的两个对象时要实现自己的compareTo,请说出您想按价格排序的AirlineTicket对象(较少排名第一),然后是中途停留的次数(再次排名第一),你会做到以下几点:
class AirlineTicket implements Comparable<Cost> { public double cost; public int stopovers; public AirlineTicket(double cost, int stopovers) { this.cost = cost; this.stopovers = stopovers ; } public int compareTo(Cost o) { if(this.cost != o.cost) return Double.compare(this.cost, o.cost); //sorting in ascending order. if(this.stopovers != o.stopovers) return this.stopovers - o.stopovers; //again, ascending but swap the two if you want descending return 0; } }
一个简单的方法来实现多个字段比较与番石榴的比较链 – 那么你可以说
public int compareTo(Foo that) { return ComparisonChain.start() .compare(lastName, that.lastName) .compare(firstName, that.firstName) .compare(zipCode, that.zipCode) .result(); }
代替
public int compareTo(Person other) { int cmp = lastName.compareTo(other.lastName); if (cmp != 0) { return cmp; } cmp = firstName.compareTo(other.firstName); if (cmp != 0) { return cmp; } return Integer.compare(zipCode, other.zipCode); } }
例如,当你想有一个排序的集合或地图
当你实现Comparable接口时,你需要实现方法compareTo。 您需要它来比较对象,以便使用例如ArrayList类的排序方法。 你需要一种比较你的对象的方法来排序它们。 所以你需要在你的类中使用自定义的compareTo方法,这样你就可以使用ArrayList排序方法。 compareTo方法返回-1,0,1。
我刚刚阅读了Java Head 2.0的相关章节,我还在学习。
Comparable用于比较你的类的实例。 我们可以从很多方面比较实例,这就是为什么我们需要实现一个方法compareTo
,以便知道我们想要比较实例的方式(属性)。
Dog
类:
package test; import java.util.Arrays; public class Main { public static void main(String[] args) { Dog d1 = new Dog("brutus"); Dog d2 = new Dog("medor"); Dog d3 = new Dog("ara"); Dog[] dogs = new Dog[3]; dogs[0] = d1; dogs[1] = d2; dogs[2] = d3; for (int i = 0; i < 3; i++) { System.out.println(dogs[i].getName()); } /** * Output: * brutus * medor * ara */ Arrays.sort(dogs, Dog.NameComparator); for (int i = 0; i < 3; i++) { System.out.println(dogs[i].getName()); } /** * Output: * ara * medor * brutus */ } }
Main
课程:
package test; import java.util.Arrays; public class Main { public static void main(String[] args) { Dog d1 = new Dog("brutus"); Dog d2 = new Dog("medor"); Dog d3 = new Dog("ara"); Dog[] dogs = new Dog[3]; dogs[0] = d1; dogs[1] = d2; dogs[2] = d3; for (int i = 0; i < 3; i++) { System.out.println(dogs[i].getName()); } /** * Output: * brutus * medor * ara */ Arrays.sort(dogs, Dog.NameComparator); for (int i = 0; i < 3; i++) { System.out.println(dogs[i].getName()); } /** * Output: * ara * medor * brutus */ } }
以下是如何在Java中使用可比较的一个很好的例子:
http://www.onjava.com/pub/a/onjava/2003/03/12/java_comp.html?page=2
好的,但是为什么不只是定义一个compareTo方法而没有实现可比的接口。 例如一个城市的名称和温度和
public int compareTo(City theOther) { if (this.temperature<theOther.temperature) return -1; else if (this.temperature>theOther.temperature) return 1; else return 0; }