在JAVA中实现对象的排序可以使用Comparable接口,也可以使用Comparator接口.
- Comparable : 需要自己实现比较的方法compareTo,是一个内部排序器
- Comparator : 可以使用其默认的方法和lambda表达式来实现排序,是一个外部排序器,更像一个工具接口
一、Comparable接口
- 表明实现的对象是一个可排序的类
1.一个需要排序的类,需要实现Comparable接口中的compareTo方法
class ArticleInfo implements Comparable<ArticleInfo> {
private Integer articleId;
private String title;
private Integer views;
private Integer comments;
private Long createTime;
public ArticleInfo(Integer articleId, String title, Integer views, Integer comments, Long createTime) {
this.articleId = articleId;
this.title = title;
this.views = views;
this.comments = comments;
this.createTime = createTime;
}
public Integer getArticleId() {
return articleId;
}
public void setArticleId(Integer articleId) {
this.articleId = articleId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getViews() {
return views;
}
public void setViews(Integer views) {
this.views = views;
}
public Integer getComments() {
return comments;
}
public void setComments(Integer comments) {
this.comments = comments;
}
public Long getCreateTime() {
return createTime;
}
public void setCreateTime(Long createTime) {
this.createTime = createTime;
}
@Override
public int compareTo(ArticleInfo info) {
if (this.views > info.getViews()) {
return -1;
} else if (this.views.equals(info.getViews())) {
return 0;
} else {
return 1;
}
}
@Override
public String toString() {
return "ArticleInfo{" +
"articleId=" + articleId +
", title='" + title + '\'' +
", views=" + views +
", comments=" + comments +
", createTime=" + createTime +
'}';
}
}
注:在实现compareTo方法时,一定要判断当两个对象的值相等的情况,不然,可能在集合对象比较时出错
2.调用排序方法
针对集合对象,可以使用
- 工具类Collections.sort方法
- 使用集合对象的sort方法
无论是Collections.sort方法还是集合对象的sort方法都可以传入一个排序方式的参数
- Comparator.naturalOrder() : 正序
- Comparator.reverseOrder() : 倒序
注:正序和倒序是相对于实现的Comparable接口的compareTo接口而言的,实现的就是正序,reverseOrder就是针对实现的CompareTo的结果再进行倒序
List<ArticleInfo> articleInfoList = new ArrayList<ArticleInfo>(10);
Long now = System.currentTimeMillis();
articleInfoList.add(new ArticleInfo(1001, "第一篇文章", 10, 2, now));
articleInfoList.add(new ArticleInfo(1002, "第二篇文章", 29, 3, now+1000));
articleInfoList.add(new ArticleInfo(1003, "第三篇文章", 9, 1, now+5000));
/**
* 1.通过Collections工具类来排序
*/
Collections.sort(articleInfoList);
System.out.println(articleInfoList);
Collections.sort(articleInfoList, Comparator.reverseOrder());
System.out.println(articleInfoList);
/**
* 2.通过List等对象的sort方法
*/
articleInfoList.sort(Comparator.reverseOrder());
System.out.println(articleInfoList);
二、Comparator接口
1.实现compare抽象方法
- 定义普通的实体类Article
class Article {
private Integer articleId;
private String title;
private Integer views;
private Integer comments;
private Long createTime;
public Article(Integer articleId, String title, Integer views, Integer comments, Long createTime) {
this.articleId = articleId;
this.title = title;
this.views = views;
this.comments = comments;
this.createTime = createTime;
}
public Integer getArticleId() {
return articleId;
}
public void setArticleId(Integer articleId) {
this.articleId = articleId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getViews() {
return views;
}
public void setViews(Integer views) {
this.views = views;
}
public Integer getComments() {
return comments;
}
public void setComments(Integer comments) {
this.comments = comments;
}
public Long getCreateTime() {
return createTime;
}
public void setCreateTime(Long createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "Article{" +
"articleId=" + articleId +
", title='" + title + '\'' +
", views=" + views +
", comments=" + comments +
", createTime=" + createTime +
'}';
}
}
- 实现compare方法
class ArticleComparator implements Comparator<Article> {
@Override
public int compare(Article a1, Article a2) {
return a1.getViews().compareTo(a2.getViews());
}
}
- 通过实现的比较器进行排序
List<Article> articleList = new ArrayList<Article>(10);
Long current = System.currentTimeMillis();
articleList.add(new Article(1001, "第一篇文章", 10, 2, current));
articleList.add(new Article(1002, "第二篇文章", 29, 3, current+1000));
articleList.add(new Article(1003, "第三篇文章", 9, 1, current+5000));
articleList.sort(new ArticleComparator());
System.out.println(articleList);
2.静态方法
- naturalOrder : 正序排列(一般使用于自定义的Comparator接口或Comparable接口)
- reverseOrder : 倒序排列(一般使用于自定义的Comparator接口或Comparable接口)
- comparing : 比较(传入一个排序函数)
- comparingInt : 比较int值
- comparingLong : 比较long型值
- comparingDouble : 比较double型值
/**
* 按views排序
*/
articleList.sort(Comparator.comparing(Article::getViews));
System.out.println(articleList);
/**
* 按comments排序
*/
articleList.sort(Comparator.comparing(Article::getComments));
System.out.println(articleList);
articleList.sort(Comparator.comparingInt(Article::getComments));
3.默认方法
- reversed : 倒序(将之前的对象进行逆向排列)
- thenComparing : 多重比较
List<Article> articleList = new ArrayList<Article>(10);
Long current = System.currentTimeMillis();
articleList.add(new Article(1001, "第一篇文章", 10, 5, current));
articleList.add(new Article(1002, "第二篇文章", 29, 3, current+1000));
articleList.add(new Article(1003, "第三篇文章", 9, 1, current+5000));
articleList.add(new Article(1004, "第四篇文章", 9, 2, current+5000));
/**
* 按views倒序排列
*/
articleList.sort(Comparator.comparing(Article::getViews).reversed());
System.out.println(articleList);
/**
* 先按views倒序,再按comments倒序
*/
articleList.sort(Comparator.comparingInt(Article::getViews).reversed().
thenComparing(Comparator.comparingInt(Article::getComments).reversed()));
System.out.println(articleList);
//[Article{articleId=1002, title='第二篇文章', views=29, comments=3, createTime=1548830876084}, Article{articleId=1001, title='第一篇文章', views=10, comments=5, createTime=1548830875084}, Article{articleId=1004, title='第四篇文章', views=9, comments=2, createTime=1548830880084}, Article{articleId=1003, title='第三篇文章', views=9, comments=1, createTime=1548830880084}]
- 通过thenComparing进行多重条件排序时,只要当前一个条件相同的情况下,才会按下一个指标进行排序(比较适合多个维度先优先级排序的场景)