Comaparable接口
---内置类
1. 常见的内部类有String,Integer,Date都是实现了java.lang包下的Comparable接口,重写其中的compareTo()方法。
例如:String类中重写compareTo()方法首先按照取两个字符串的公共长度进行挨个比较,按照字符顺序返回比较结果,若公共长度下两个字符串一样,则返回长度差
比较结果:
整数:大于
负数:小于
0:相等
2,那么对于Arrays类的sort方法(对于数组的排序)和Collections的sorts方法(对于容器的排序),就取决于数组和容器中的元素类型来调用各自类的compareTo()方法,实现排序。
---自定义类
那么对于自定义的排序我们同样实现了java lang包下的Comparable接口,重写其中的compareTo()方法。
比如对于一些新闻条目进行时间,标题,点击量的排序,我们就可以自己实现
import java.text.SimpleDateFormat;
import java.util.Date;
public class NewsItem implements Comparable<NewsItem>{
private String title;
private int hits;
private Date pubTime;
public NewsItem(){
}
public NewsItem(String title, int hits, Date pubTime) {
super();
this.title = title;
this.hits = hits;
this.pubTime = pubTime.;
}
/*加上setter和getter方法*/
@Override
public int compareTo(NewsItem o) { //重写compareTo方法,实现自己的比较规则
int result=0;
//时间降序,分别调用各自类型的comapreTo()方法
result=-this.pubTime.compareTo(o.pubTime); 在sort排序是默认是升序,我们要降序所以在前面加负号
if(result==0){
result=this.hits-o.hits; //点击量升序
if(result==0){
result=-this.title.compareTo(o.title); //标题降序
}
}
return result;
}
/**为了后面方面我们重写toString方法
*注意在打印的时候,系统会自动调用toString()方法
*/
@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)).
sb.append(" 点击量是:").append(this.hits).append('\n');
return sb.toString();
}
}
那后续对内容是NewsItem的数组或是列表,我们在调用sort()方法时,就会按照我们自己定义的排序规则进行排序。
Comparator接口
---内置类
首先Comparator是位于java.util下的接口,我们可以称之为比较类
那比如有一个问题,当你想只通过字符串的长度比较两个字符串,那你调用String类自己的compareTo()方法显然是做不到的,这个时候我们就可以借助Comparator接口,实现接口中的compare方法。如下:
public class StringComp implements Comparator<String>{
/**
* 按照长度比较
*/
@Override
public int compare(String o1, String o2) {
int len1=o1.length();
int len2=o2.length();
return len1-len2;
}
}
那比如我们有一个字符串列表
List<String> list=new ArrayList();
list.add("adc");
list.add("a");
list.add("abcd");
list.add("adesc");
list.add("de");
我们通过Collections.sort(list,new StringComp())就可以实现按照长度对字符串进行排序
---自定义类
如上所述,我们的自定义类都有自己的比较规则,那比如淘宝货物我们会点积按照价格排序,或者按照收藏排序也就是排序规则是独立的,这个时候我们用Comparable接口是实现不了的,解决方法是为每个排序规则实现比较类。
首先我们定义货物类:
//不实现任何接口的类
public class Goods {
//商品名称
private String name;
//商品价格
private double price;
//销量
private int fav;
public Goods(String name, double price, int fav) {
super();
this.name = name;
this.price = price;
this.fav = fav;
}
/*加上构造方法和setter,getter方法*/
@Override
public String toString() {
return "Goods name=" + name + ", price=" + price + ", fav=" + fav+"\n";
}
}
那我们先为价格的排序规则实现业务类实现Comparator类,重写compare方法:
//按照价格排序:降序
public class GoodsPriceComp implements java.util.Comparator<Goods>{
@Override
public int compare(Goods o1, Goods o2) {
// TODO Auto-generated method stub
return -(o1.getPrice()-o2.getPrice()>0?1:(o1.getPrice()-o2.getPrice()<0?-1:0));
}
}
使用:
public class GoodsApp {
public static void main(String args[]){
List<Goods> goods =new ArrayList();
goods.add(new Goods("短袖",100,2000));
goods.add(new Goods("大衣",400,158));
goods.add(new Goods("短裤",150,1000));
Collections.sort(goods, new GoodsPriceComp());
System.out.print(goods);
}
}
结果:
[Goods name=大衣, price=400.0, fav=158
, Goods name=短裤, price=150.0, fav=1000
, Goods name=短袖, price=100.0, fav=2000
]
那同理我们也可以为商品名称和销量各自实现排序类,这样与实体类分开,也可以方便修改排序规则,各个排序规则也清楚明白。