引用类型的自定义数据排序——高淇JAVA300讲笔记
自定义类的排序
1.实体类
实现java.lang.Comparable接口,重写compareTo方法
2.业务排序类
实现java.util.Comparator接口,重写compare方法。一般工作中推荐使用这种,因为比较灵活,可以为每一个单独的排序方法写一个业务排序类。
案例一:实现Comparable接口进行排序
有一个新闻类,要求按时间降序+点击量升序+标题降序。
先写一个新闻类,这个类实现了java.lang.Comparable接口,并重写了compareTo()方法。
1 package com.bjsxt.sort.refType; 2 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 6 /** 7 * 新闻条目实体类 8 * 9 */ 10 public class NewsItem implements java.lang.Comparable<NewsItem>{ 11 //标题 12 private String title; 13 //点击量 14 private int hits; 15 //时间 16 private Date pubTime; 17 18 //无参构造器 19 public NewsItem() { 20 super(); 21 } 22 //带参构造器 23 public NewsItem(String title, int hits, Date pubTime) { 24 super(); 25 this.title = title; 26 this.hits = hits; 27 this.pubTime = pubTime; 28 } 29 30 public String getTitle() { 31 return title; 32 } 33 public void setTitle(String title) { 34 this.title = title; 35 } 36 public int getHits() { 37 return hits; 38 } 39 public void setHits(int hits) { 40 this.hits = hits; 41 } 42 public Date getPubTime() { 43 return pubTime; 44 } 45 public void setPubTime(Date pubTime) { 46 this.pubTime = pubTime; 47 } 48 49 //时间降序+点击量升序+标题降序 50 @Override 51 public int compareTo(NewsItem o) { 52 int result = 0; 53 //比较时间 54 result = -this.pubTime.compareTo(o.pubTime); //降序 55 if(0 == result) { //时间相同 56 //点击量 57 result = this.hits - o.hits; //升序 58 if(0 == result) { //点击量相同 59 //标题 60 result = -this.title.compareTo(o.title); //降序 61 } 62 } 63 64 return result; 65 } 66 @Override 67 public String toString() { 68 StringBuilder sb = new StringBuilder(); 69 sb.append("标题:").append(this.title); 70 sb.append(",时间:").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.pubTime)); 71 sb.append(",点击量:").append(this.hits).append("\n"); 72 return sb.toString(); 73 } 74 75 }
然后再写一个类使用Collections进行排序:
1 package com.bjsxt.sort.refType; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.Date; 6 import java.util.List; 7 8 /** 9 * 使用Collections 10 * 11 */ 12 public class NewsItemApp { 13 14 public static void main(String[] args) { 15 List<NewsItem> news = new ArrayList<NewsItem>(); 16 news.add(new NewsItem("美国后怕了,逃跑了悲剧了",50,new Date(System.currentTimeMillis()-1000*60*60))); 17 news.add(new NewsItem("中国登上钓鱼岛了,全国欢呼了",100,new Date())); 18 news.add(new NewsItem("小日本终于听话了,泪流满面笑了",60,new Date(System.currentTimeMillis()-1000*60*60))); 19 System.out.println("排序前:" + news); 20 //排序 21 Collections.sort(news); 22 System.out.println("排序后:" + news); 23 24 } 25 }
运行结果:
排序前:[标题:美国后怕了,逃跑了悲剧了,时间:2018-01-21 11:04:57,点击量:50 , 标题:中国登上钓鱼岛了,全国欢呼了,时间:2018-01-21 12:04:57,点击量:100 , 标题:小日本终于听话了,泪流满面笑了,时间:2018-01-21 11:04:57,点击量:60 ] 排序后:[标题:中国登上钓鱼岛了,全国欢呼了,时间:2018-01-21 12:04:57,点击量:100 , 标题:美国后怕了,逃跑了悲剧了,时间:2018-01-21 11:04:57,点击量:50 , 标题:小日本终于听话了,泪流满面笑了,时间:2018-01-21 11:04:57,点击量:60 ]
案例二:实现Comparator接口进行排序
可以分别按照商品的价格、收藏量排序。
先写一个商品的实体类,在这里实体类就不用实现接口了,比较独立。
1 package com.bjsxt.sort.refType; 2 3 /** 4 * 实体类 5 * 6 */ 7 public class Goods { 8 //商品名称 9 private String name; 10 //价格 11 private double price; 12 //收藏量 13 private int fav; 14 15 //无参构造器 16 public Goods() { 17 super(); 18 } 19 20 //有参构造器 21 public Goods(String name, double price, int fav) { 22 super(); 23 this.name = name; 24 this.price = price; 25 this.fav = fav; 26 } 27 28 public String getName() { 29 return name; 30 } 31 public void setName(String name) { 32 this.name = name; 33 } 34 public double getPrice() { 35 return price; 36 } 37 public void setPrice(double price) { 38 this.price = price; 39 } 40 public int getFav() { 41 return fav; 42 } 43 public void setFav(int fav) { 44 this.fav = fav; 45 } 46 47 @Override 48 public String toString() { 49 return "商品名:"+name+",收藏量:"+this.fav+",价格:"+this.price+"\n"; 50 } 51 52 }
然后写业务比较器,在这里实现java.util.Comparator接口,然后重写compare方法。这里分别写了按价格降序,按收藏量升序。如果自己想要其他的排序方式,可以另外单独再写业务比较器,非常灵活。
1 package com.bjsxt.sort.refType; 2 3 /** 4 * 按价格排序的业务类(降序) 5 * 6 */ 7 public class GoodsPriceComp implements java.util.Comparator<Goods>{ 8 9 @Override 10 public int compare(Goods o1, Goods o2) { 11 return -(o1.getPrice()-o2.getPrice()>0?1:(o1.getClass()==o2.getClass()?0:-1)); 12 } 13 14 }
1 package com.bjsxt.sort.refType; 2 3 /** 4 * 按收藏量排序的业务类(升序) 5 * 6 */ 7 public class GoodsFavComp implements java.util.Comparator<Goods>{ 8 9 @Override 10 public int compare(Goods o1, Goods o2) { 11 return o1.getFav()-o2.getFav(); 12 } 13 14 }
最后用Collections进行排序:
package com.bjsxt.sort.refType; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class GoodsApp { public static void main(String[] args) { List<Goods> list = new ArrayList<Goods>(); list.add(new Goods("老马视频",100,2000)); list.add(new Goods("老高视频",50,2000)); list.add(new Goods("老裴视频",1000,1000)); System.out.println("排序前:"+list); // Collections.sort(list,new GoodsPriceComp()); Collections.sort(list,new GoodsFavComp()); System.out.println("排序后:"+list); } }
运行结果:
排序前:[商品名:老马视频,收藏量:2000,价格:100.0 , 商品名:老高视频,收藏量:2000,价格:50.0 , 商品名:老裴视频,收藏量:1000,价格:1000.0 ] 排序后:[商品名:老裴视频,收藏量:1000,价格:1000.0 , 商品名:老马视频,收藏量:2000,价格:100.0 , 商品名:老高视频,收藏量:2000,价格:50.0 ]