Java中實現物件的比較:Comparable介面和Comparator介面
在實際應用中,我們往往有需要比較兩個自定義物件大小的地方。而這些自定義物件的比較,就不像簡單的整型資料那麼簡單,它們往往包含有許多的屬性,我們一般都是根據這些屬性對自定義物件進行比較的。所以Java中要比較物件的大小或者要對物件的集合進行排序,需要通過比較這些物件的某些屬性的大小來確定它們之間的大小關係。
一般,Java中通過介面實現兩個物件的比較,比較常用就是Comparable介面和Comparator介面。首先類要實現介面,並且使用泛型規定要進行比較的物件所屬的類,然後類實現了介面後,還需要實現介面定義的比較方法(compareTo方法或者compare方法),在這些方法中傳入需要比較大小的另一個物件,通過選定的成員變數與之比較,如果大於則返回1,小於返回-1,相等返回0。
一、Comparable介面
1.什麼是Comparable介面
此介面強行對實現它的每個類的物件進行整體排序。此排序被稱為該類的自然排序 ,類的 compareTo方法被稱為它的自然比較方法 。實現此介面的物件列表(和陣列)可以通過 Collections.sort(和 Arrays.sort )進行自動排序。實現此介面的物件可以用作有序對映表中的鍵或有序集合中的元素,無需指定比較器。
2.實現什麼方法
int compareTo(T o)
比較此物件與指定物件的順序。如果該物件小於、等於或大於指定物件,則分別返回負整數、零或正整數。
引數: o - 要比較的物件。
返回:負整數、零或正整數,根據此物件是小於、等於還是大於指定物件。
丟擲:ClassCastException - 如果指定物件的型別不允許它與此物件進行比較。
3.例項
package com.mxl.algorithlm; import java.util.Date; /** * 因為要實現對ConsumInfo物件的排序,所以在ConsunInfo類中要實現Comparable介面,也就是要實現compareTo()方法 * 具體的比較參照:依次按照price、uid進行倒序排序 * @author breeze * */ public class ConsumInfo implements Comparable<ConsumInfo> { private int uid; private String name; private double price; private Date datetime; public ConsumInfo() { // TODO Auto-generated constructor stub } public ConsumInfo(int uid,String name,double price,Date datetime){ this.uid = uid; this.name = name; this.price = price; this.datetime = datetime; } public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public Date getDatetime() { return datetime; } public void setDatetime(Date datetime) { this.datetime = datetime; } @Override public String toString() { return "ConsumInfo [uid=" + uid + ", name=" + name + ", price=" + price + ", datetime=" + datetime + "]"; } /** * 這裡比較的是什麼, Collections.sort方法實現的就是按照此比較的東西排列 * 順序(從小到大): * if(price < o.price){ return -1; } if(price > o.price){ return 1; } * 倒序(從大到小): * if(price < o.price){ return 1; } if(price > o.price){ return -1; } * */ @Override public int compareTo(ConsumInfo o) { //首先比較price,如果price相同,則比較uid if(price < o.price){ return -1; } if(price > o.price){ return 1; } if(price == o.price){ if(uid < o.uid){ return -1; } if(uid > o.uid){ return 1; } } return 0; } } //測試類 package com.mxl.algorithlm; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; public class ConsumInfoTest { public static void main(String[] args) { ConsumInfo consumInfo1 = new ConsumInfo(100, "consumInfo1", 400.0,new Date()); ConsumInfo consumInfo2 = new ConsumInfo(200, "consumInfo1", 200.0,new Date()); ConsumInfo consumInfo3 = new ConsumInfo(300, "consumInfo1", 100.0,new Date()); ConsumInfo consumInfo4 = new ConsumInfo(400, "consumInfo1", 700.0,new Date()); ConsumInfo consumInfo5 = new ConsumInfo(500, "consumInfo1", 800.0,new Date()); ConsumInfo consumInfo6 = new ConsumInfo(600, "consumInfo1", 300.0,new Date()); ConsumInfo consumInfo7 = new ConsumInfo(700, "consumInfo1", 900.0,new Date()); ConsumInfo consumInfo8 = new ConsumInfo(800, "consumInfo1", 400.0,new Date()); List<ConsumInfo> list = new ArrayList<ConsumInfo>(); list.add(consumInfo1); list.add(consumInfo2); list.add(consumInfo3); list.add(consumInfo4); list.add(consumInfo5); list.add(consumInfo6); list.add(consumInfo7); list.add(consumInfo8); System.out.println("排序前:"); //排序前 for(ConsumInfo consumInfo : list ){ System.out.println(consumInfo); } Collections.sort(list);//排序 System.out.println("排序後:"); //排序後 for(ConsumInfo consumInfo :list){ System.out.println(consumInfo); } } }
二、Comparator介面
與上面的Comparable介面不同的是:
①、Comparator位於包java.util下,而Comparable位於包java.lang下。
②、Comparable介面將比較程式碼嵌入需要進行比較的類的自身程式碼中,而Comparator介面在一個獨立的類中實現比較。
③、如果前期類的設計沒有考慮到類的Compare問題而沒有實現Comparable介面,後期可以通過Comparator介面來實現比較演算法進行排序,並且為了使用不同的排序標準做準備,比如:升序、降序。
④、Comparable介面強制進行自然排序,而Comparator介面不強制進行自然排序,可以指定排序順序。
使用例項:
package test;
import java.util.Comparator;
/**
* 具體的比較類(比較器),實現Comparator介面
* @author breeze
*
*/
public class ComparatorConsunInfo implements Comparator<ConsumInfo> {
/**
* 順序(從小到大):
* if(price < o.price){
return -1;
}
if(price > o.price){
return 1;
}
* 倒序(從大到小):
* if(price < o.price){
return 1;
}
if(price > o.price){
return -1;
}
*/
@Override
public int compare(ConsumInfo o1, ConsumInfo o2) {
//首先比較price,如果price相同,則比較uid
if(o1.getPrice() > o2.getPrice()){
return 1;
}
if(o1.getPrice() < o2.getPrice()){
return -1;
}
if(o1.getPrice() == o2.getPrice()){
if(o1.getUid() > o2.getUid()){
return 1;
}
if(o1.getUid() < o2.getUid()){
return -1;
}
}
return 0;
}
}
/**
* 需要進行比較的類
* @author breeze
*
*/
public class ConsumInfo{
private int uid;
private String name;
private double price;
private Date datetime;
public ConsumInfo() {
// TODO Auto-generated constructor stub
}
public ConsumInfo(int uid,String name,double price,Date datetime){
this.uid = uid;
this.name = name;
this.price = price;
this.datetime = datetime;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Date getDatetime() {
return datetime;
}
public void setDatetime(Date datetime) {
this.datetime = datetime;
}
@Override
public String toString() {
return "ConsumInfo [uid=" + uid + ", name=" + name + ", price=" + price
+ ", datetime=" + datetime + "]";
}
}
//測試類
public class ConsumInfoTest {
public static void main(String[] args) {
ConsumInfo consumInfo1 = new ConsumInfo(100, "consumInfo1", 400.0,new Date());
ConsumInfo consumInfo2 = new ConsumInfo(200, "consumInfo1", 200.0,new Date());
ConsumInfo consumInfo3 = new ConsumInfo(300, "consumInfo1", 100.0,new Date());
ConsumInfo consumInfo4 = new ConsumInfo(400, "consumInfo1", 700.0,new Date());
ConsumInfo consumInfo5 = new ConsumInfo(500, "consumInfo1", 800.0,new Date());
ConsumInfo consumInfo6 = new ConsumInfo(600, "consumInfo1", 300.0,new Date());
ConsumInfo consumInfo7 = new ConsumInfo(700, "consumInfo1", 900.0,new Date());
ConsumInfo consumInfo8 = new ConsumInfo(800, "consumInfo1", 400.0,new Date());
List<ConsumInfo> list = new ArrayList<ConsumInfo>();
list.add(consumInfo1);
list.add(consumInfo2);
list.add(consumInfo3);
list.add(consumInfo4);
list.add(consumInfo5);
list.add(consumInfo6);
list.add(consumInfo7);
list.add(consumInfo8);
System.out.println("排序前:");
//排序前
for(ConsumInfo consumInfo : list ){
System.out.println(consumInfo);
}
ComparatorConsunInfo comparatorConsunInfo = new ComparatorConsunInfo();//比較器
Collections.sort(list,comparatorConsunInfo);//排序
System.out.println("排序後:");
//排序後
for(ConsumInfo consumInfo :list){
System.out.println(consumInfo);
}
}
}