自定义引用类型放入集合中,按实际业务需求进行排序的两种思路
第一种思路:
(1)自定义实体类实现java.lang.Comparable接口,重写public int compareTo(Object obj)方法。自定义业务比较规则
(2)利用java.util.Collections类的静态方法sort(List<自定义类型> list)进行排序(默认升序)或者。自己编写排序工具类。冒泡+compareTo(obj)方法
例子:新闻条目的排序
需要排序的实体类,实现Comparable接口,重写方法,自定义排序规则
1 package com.zdxy.shangxiaofei; 2 3 import java.text.SimpleDateFormat; 4 import java.util.Collections; 5 import java.util.Date; 6 7 import javax.tools.JavaCompiler; 8 9 /** 10 * 新闻条目的实体类 11 * 按时间,点击量,标题。排序 12 * 【1】时间降序 13 * 【2】时间相同,点击量升 14 * 【3】时间相同,点击量相同,标题长度降序。 15 * @ClassName: NewItem 16 * @Description: TODO(这里用一句话描述这个类的作用) 17 * @author 尚晓飞 18 * @date 2014-8-8 下午6:53:18 19 * 20 */ 21 public class NewItem implements java.lang.Comparable<NewItem>{ 22 private String title;//标题 23 private int hits;//点击量 24 private Date pubTime;//发布时间 25 26 public NewItem() { 27 super(); 28 } 29 30 31 /** 32 * 第一种思路:实体类实现java.lang.Comparable接口,compareTo方法,在方法中写排序规则 33 * 34 * 时间降序+点击量升序+标题降序 35 * @Title: compareTo 36 * @Description: TODO(这里用一句话描述这个方法的作用) 37 * @author 尚晓飞 38 * @date 2014-8-8 下午6:59:03 39 * @param o 40 * @return 41 * @see java.lang.Comparable#compareTo(java.lang.Object) 42 */ 43 @Override 44 public int compareTo(NewItem o) { 45 // TODO Auto-generated method stub 46 int result=0; 47 //比较发布时间(降序)(内置时间类,有排序功能,但是是升序) 48 result=-this.pubTime.compareTo(o.pubTime); 49 //如果发布时间相同,则按点击量排序 50 if(0==result){ 51 //比较点击量(升序) 52 result=this.hits-o.hits; 53 //如果点击量相同,则按标题长度排序(降序) 54 if(0==result){ 55 //比较标题(长度降序) 56 result=-this.title.compareTo(o.title); 57 return result; 58 }else{ 59 return result; 60 } 61 }else{ 62 return result; 63 } 64 } 65 66 67 /** 68 * 重写toString方法,方便测试打印 69 * @Title: toString 70 * @Description: TODO(这里用一句话描述这个方法的作用) 71 * @author 尚晓飞 72 * @date 2014-8-8 下午7:20:55 73 * @return 74 * @see java.lang.Object#toString() 75 */ 76 @Override 77 public String toString() { 78 StringBuilder sb=new StringBuilder(); 79 sb.append("标题:").append(this.title); 80 sb.append("---发布时间:").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.pubTime));//将时间按某种格式输出 81 sb.append("---点击量:").append(this.hits).append(" ");//加一个回车 82 83 return sb.toString(); 84 85 } 86 87 88 public NewItem(String title, int hits, Date pubTime) { 89 super(); 90 this.title = title; 91 this.hits = hits; 92 this.pubTime = pubTime; 93 } 94 95 public String getTitle() { 96 return title; 97 } 98 99 public void setTitle(String title) { 100 this.title = title; 101 } 102 103 public int getHits() { 104 return hits; 105 } 106 107 public void setHits(int hits) { 108 this.hits = hits; 109 } 110 111 public Date getPubTime() { 112 return pubTime; 113 } 114 115 public void setPubTime(Date pubTime) { 116 this.pubTime = pubTime; 117 } 118 119 120 }
利用Collections工具类,对实体类的集合进行排序
1 package com.zdxy.shangxiaofei; 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进行集合排序(Collections中的排序默认是升序) 10 * @ClassName: Test 11 * @Description: TODO(这里用一句话描述这个类的作用) 12 * @author 尚晓飞 13 * @date 2014-8-8 下午7:12:03 14 * 15 */ 16 public class Test { 17 public static void main(String[] args) { 18 List<NewItem> news=new ArrayList<NewItem>(); 19 news.add(new NewItem("小日本,听话,泪流满面",60,new Date(System.currentTimeMillis()-1000*60*60))); 20 news.add(new NewItem("中国登上钓鱼岛了,全国欢呼",100,new Date())); 21 news.add(new NewItem("美国后怕了,逃跑了悲剧了", 50, new Date(System.currentTimeMillis()-1000*60*60))); 22 23 //要求,先按时间降序,再按点击量升序,后按标题降序 24 25 //排序前 26 System.out.println("排序前:"+news); 27 28 //排序 29 Collections.sort(news); 30 31 //排序后 32 System.out.println("排序后:"+news); 33 34 /** 35 * 打印结果 36 * 排序前:[标题:小日本,听话,泪流满面---发布时间:2014-08-08 18:35:14---点击量:60 37 , 标题:中国登上钓鱼岛了,全国欢呼---发布时间:2014-08-08 19:35:14---点击量:100 38 , 标题:美国后怕了,逃跑了悲剧了---发布时间:2014-08-08 18:35:14---点击量:50 39 ] 40 排序后:[标题:中国登上钓鱼岛了,全国欢呼---发布时间:2014-08-08 19:35:14---点击量:100 41 , 标题:美国后怕了,逃跑了悲剧了---发布时间:2014-08-08 18:35:14---点击量:50 42 , 标题:小日本,听话,泪流满面---发布时间:2014-08-08 18:35:14---点击量:60] 43 */ 44 } 45 }
第二种思路
(1)自己编写业务比较规则类。实体类不用实现任何借口。业务比较规则类实现java.util.Comparator接口。重写public int compare(String o1, String o2)方法,编写排序规则
(2)利用java.util.Collections类的静态方法sort(List<自定义类型> list)进行排序(默认升序)或者。自己编写排序工具类。冒泡+compareTo(obj)方法
一般推荐使用第二种思路。
第二种思路(1)排序规则和实体类解耦。当业务发生变化,可以灵活改变。
(2)如果项目是接手别的公司,实体类无源代码,则可以编写排序规则业务类。
例子:淘宝商品的排序
实体类+自定义的排序业务类
1 package com.zdxy.shangxiaofei; 2 /** 3 *按商品的收藏量降序 4 *按商品的价格升序 5 *按商品的名字降序 6 * @ClassName: Goods 7 * @Description: TODO(这里用一句话描述这个类的作用) 8 * @author 尚晓飞 9 * @date 2014-8-8 下午7:45:28 10 * 11 */ 12 public class Goods { 13 private int fav;//收藏量 14 private double price;//价格 15 private String name;//商品名 16 17 public Goods() { 18 super(); 19 } 20 21 public Goods(int fav, double price, String name) { 22 super(); 23 this.fav = fav; 24 this.price = price; 25 this.name = name; 26 } 27 28 /** 29 * 重写toString()便于测试 30 * @Title: toString 31 * @Description: TODO(这里用一句话描述这个方法的作用) 32 * @author 尚晓飞 33 * @date 2014-8-8 下午7:49:03 34 * @return 35 * @see java.lang.Object#toString() 36 */ 37 @Override 38 public String toString() { 39 return "商品名:"+this.name+"---收藏量"+this.fav+"---价格:"+this.price; 40 } 41 42 public int getFav() { 43 return fav; 44 } 45 46 public void setFav(int fav) { 47 this.fav = fav; 48 } 49 50 public double getPrice() { 51 return price; 52 } 53 54 public void setPrice(double price) { 55 this.price = price; 56 } 57 58 public String getName() { 59 return name; 60 } 61 62 public void setName(String name) { 63 this.name = name; 64 } 65 66 67 68 69 70 71 } 72 73 74 /** 75 * 只按收藏量进行降序排序的排序业务类 76 * @ClassName: FavComparator 77 * @Description: TODO(这里用一句话描述这个类的作用) 78 * @author 尚晓飞 79 * @date 2014-8-11 上午8:54:22 80 * 81 */ 82 public class FavComparator implements java.util.Comparator<Goods> { 83 84 @Override 85 public int compare(Goods o1, Goods o2) { 86 // TODO Auto-generated method stub 87 int o1Fav=o1.getFav(); 88 int o2Fav=o2.getFav(); 89 return -(o1Fav-o2Fav);//因为Collections.sort(list,comparator)默认是升序,所以需要加-号 90 } 91 92 } 93 94 95 /** 96 * 自定义业务排序类,与实体类解耦。 97 * 业务需求: 98 * 【1】先按收藏量进行降序 99 * 【2】收藏量相同,则按价格升序 100 * 【3】收藏量和价格都相同,则按名字降序 101 * @ClassName: AllComparator 102 * @Description: TODO(这里用一句话描述这个类的作用) 103 * @author 尚晓飞 104 * @date 2014-8-11 上午9:05:38 105 * 106 */ 107 public class AllComparator implements java.util.Comparator<Goods> { 108 109 @Override 110 public int compare(Goods o1, Goods o2) { 111 112 int result=0; 113 //先按收藏量进行排序(降序) 114 result=-(o1.getFav()-o2.getFav()); 115 //如果收藏量相同,相减为O,则按价格升序 116 if(result==0){ 117 //按价格进行排序(升序) 118 result=o1.getPrice()-o2.getPrice()>0?1:(o1.getPrice()-o2.getPrice()==0?0:-1); 119 //如果价格相同,则按,名字进行降序 120 if(result==0){ 121 //名字降序 122 result=-(o1.getName().compareTo(o2.getName())); 123 } 124 } 125 126 return result; 127 } 128 129 130 }
利用Collections工具类,对装有商品对象的集合类进行排序
1 package com.zdxy.shangxiaofei; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.List; 6 7 /** 8 * 9 * @ClassName: Test2 10 * @Description: TODO(这里用一句话描述这个类的作用) 11 * @author 尚晓飞 12 * @date 2014-8-8 下午7:52:40 13 * 14 */ 15 public class Test2 { 16 public static void main(String[] args) { 17 List<Goods> list=new ArrayList<Goods>(); 18 list.add(new Goods(10, 100, "面包")); 19 20 list.add(new Goods(50, 200, "a")); 21 list.add(new Goods(50,200,"k")); 22 list.add(new Goods(50, 200, "z")); 23 list.add(new Goods(100, 300, "包子油条")); 24 list.add(new Goods(50, 100, "牛奶")); 25 //排序前 26 System.out.println("排序前:"+list); 27 28 //排序 29 Collections.sort(list, new AllComparator()); 30 31 //排序后() 32 System.out.println("排序后:"+list); 33 } 34 35 //只按收藏量进行排序的业务类的测试 36 public static void testSort1(List list){ 37 //排序前 38 System.out.println("排序前:"+list); 39 40 //排序 41 Collections.sort(list, new FavComparator()); 42 43 //排序后(收藏量的降序) 44 System.out.println("排序后:"+list); 45 } 46 }