Compareable接口和Comparator接口
实体类: java.lang.Comparable(接口)+compareTo(重写方法)
业务类:java.util.Comparator(接口) +compare(重写方法)
两个接口分别对应的业务实现
在实际的需求中,我们根据对象的各种属性(标题,时间,点击率,销售额。。。)进行排序(升序,降序),可以做哎数据库的sql上进行处理,但是不是每一个场景都适合在sql上进行处理,我们有时候需要在程序根据不同的属性,对一个对象进行各种排序通过页面呈现给用户。
一、Comparable接口+compareTo方法 的应用场景
下面有这样的一个需求,一种商品(商品名,销售量,生产日期),根据生产日期降序 销售量升序 商品名称降序
思路:首先按照日期降序,如果日期相同 按照销售量升序,如果销售量相同,按周商品的名称降序。
- 创建类实现Comparable接口(注意有泛型),重写compareTo方法
/**
* 商品po类
*/
public class Items implements java.lang.Comparable<Items> {
private String title;
private int hits;
private Date pubTime;
public Items() {}
public Items(String title, int hits, Date pubTime) {
super();
this.title = title;
this.hits = hits;
this.pubTime = pubTime;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getHits() {
return hits;
}
public void setHits(int hits) {
this.hits = hits;
}
public Date getPubTime() {
return pubTime;
}
public void setPubTime(Date pubTime) {
this.pubTime = pubTime;
}
//时间降序 点击量升序 标题降序
@Override
public int compareTo(Items o) {
int result = 0;
//按照生产时间降序
result = - this.pubTime.compareTo(o.pubTime);
if(0==result){//如果生产时间相同 就按照销售量升序排列
result = this.hits-o.hits;
if(0==result){//如果销售量相同 按照名字降序排列
result = - this.title.compareTo(o.title);
}
}
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("商品名称").append(this.title);
sb.append("销售量").append(this.hits);
sb.append("生产时间").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.pubTime)).append("\n");
return sb.toString();
}
}
- 造数据,进行比较
注意:最后排序还是要调用Collenctions.sort(item)
方法进行排序
//时间降序, 销售量升序, 标题降序
public static void main(String[] args) {
List<Items> item
= new ArrayList<Items>();
item.add(new Items("abcitems"
,30,new Date(System.currentTimeMillis()-1000*60*60)));
item.add(new Items("abcfgitems"
,30,new Date(System.currentTimeMillis()-1000*60*50)));
item.add(new Items("abcditems"
,100,new Date()));
item.add(new Items("abefNews"
,50,new Date(System.currentTimeMillis()-1000*60*60)));
System.out.println("----------排序前----------");
System.out.println(item);
System.out.println("----------排序后----------");
Collections.sort(item);
System.out.println(item);
}
二,Comparator接口 + compare方法 的应用场景
一般比较字符串是按照unicode的大小进行排序的,但是我需要按照字符串的长度进行排序,下面是实现的案例:
首先,定义比较的业务规则
/**
* 定义业务的比较规则,我需要按照字符串的长度进行比较(在实际的场景中,可以根据业务的需求,灵活的改变比较规则,实现排序)
*/
public class CompareString implements java.util.Comparator<String> {
@Override
public int compare(String o1, String o2) {
int len1 = o1.length();
int len2 = o2.length();
return -(len1-len2);//需要按照降序排列
}
}
比较字符串的长度,按照降序排列
注意:最后排序还是调用Collections.sort(list, new CompareString()
方法
public static void main(String[] args) {
List<String> list
= new ArrayList<String>();
list.add("abc");
list.add("abcd");
list.add("ab");
list.add("abd");
Collections.sort(list,new CompareString());
System.out.println(list);
//[abcd, abc, abd, ab]
}
三、对比
- comparable接口是默认嵌套在实现类里面,当我们调用
Collections.sort(list)
方法会自动调用重写的compareTo方法。 - comparator接口是类似工具类,提前在外面定义一个工具类实现comparator接口,并重写compare方法。当我们需要排序时,调用该工具类,通过
Collections.sort(list, 工具类对象)
的方式调用。