java 实现Comparable接口排序,升序、降序、倒叙

时间:2021-11-09 00:07:00

本人由于项目开发中需要对查询结果list进行排序,这里根据的是每一个对象中的创建时间降序排序。本人讲解不深,只实现目的,如需理解原理还需查阅更深的资料。

1.实现的效果

java 实现Comparable接口排序,升序、降序、倒叙

2.创建排序的对象

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package com.practice.test.comparable;
import java.util.Date;
 
/**
 * 描述:要比较的对象
 *
 * @author cui
 * @create 2018-12-18 14:07
 */
public class MySortBean implements Comparable<MySortBean> {
  private String name;
  private int age;
  private Date createTime;
 
 
  public String getName() {
    return name;
  }
 
  public void setName(String name) {
    this.name = name;
  }
 
  public int getAge() {
    return age;
  }
 
  public void setAge(int age) {
    this.age = age;
  }
 
  public Date getCreateTime() {
    return createTime;
  }
 
  public void setCreateTime(Date createTime) {
    this.createTime = createTime;
  }
 
//  @Override
//  public int compareTo(MySortBean o) {
//    if (this.age>o.age){
//      return -1;
//    }else if (this.age==o.age){
//      return 0;
//    }
//    return 1;
//  }
    @Override
    public int compareTo(MySortBean o) {
      if (this.createTime.compareTo(o.getCreateTime())>0){
        return -1;
      }else if (this.createTime.compareTo(o.getCreateTime())==0){
        return 0;
      }
      return 1;
    }
 
  @Override
  public String toString() {
    return "MySortBean{" +
        "name='" + name + '\'' +
        ", age=" + age +
        '}';
  }
}

3.编写test方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package com.practice.test;
import com.practice.test.comparable.MySortBean;
import com.spring.testlist.util.DateUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
/**
 * 描述:
 * 测试比较器
 *
 * @author cui
 * @create 2018-12-18 14:10
 */
@RunWith(SpringJUnit4ClassRunner.class)
public class TestCompare {
 
  @Test
  public void testComparable(){
    MySortBean m1 = new MySortBean();
    m1.setAge(1);
    m1.setCreateTime(DateUtil.parseDate("2019-01-21 16:13:18"));
    MySortBean m2 = new MySortBean();
    m2.setAge(2);
    m2.setCreateTime(DateUtil.parseDate("2019-01-23 16:13:18"));
    MySortBean m3 = new MySortBean();
    m3.setAge(3);
    m3.setCreateTime(DateUtil.parseDate("2019-01-22 16:13:18"));
    MySortBean m4 = new MySortBean();
    m4.setAge(4);
    m4.setCreateTime(DateUtil.parseDate("2019-01-24 16:13:18"));
    MySortBean m5 = new MySortBean();
    m5.setAge(5);
    m5.setCreateTime(DateUtil.parseDate("2019-01-25 16:13:18"));
    List<MySortBean> l = new ArrayList<>(5);
    l.add(m1);
    l.add(m2);
    l.add(m4);
    l.add(m5);
    l.add(m3);
 
    System.out.println("排序前:");
    for (MySortBean i:l) {
      System.out.println(DateUtil.formatDate(i.getCreateTime(),"yyyy-MM-dd HH:mm:ss"));
    }
    /**
     * 自定义排序
     * 直接return -1 倒叙排列,list顺序颠倒输出
     *
     * if (o1.getAge()>o2.getAge()){
     *           return 1;
     *         }
     *         return -1;
     *         以上升序输出
     *
     * if (o1.getAge()>o2.getAge()){
     *           return -1;
     *         }
     *         return 1;
     *         以上降序输出
     *
     *
     */
/*    Comparator<MySortBean> comparator = new Comparator<MySortBean>() {
      @Override
      public int compare(MySortBean o1,MySortBean o2) {
        if (o1.getAge()>o2.getAge()){
          return -1;
        }
        return 1;
      }
    };
    l.sort(comparator);*/
    l.sort(MySortBean::compareTo);
    System.out.println("--------");
    System.out.println("排序后:");
    for (MySortBean i:l) {
      System.out.println(DateUtil.formatDate(i.getCreateTime(),"yyyy-MM-dd HH:mm:ss"));
    }
  }
}

4.时间格式化工具类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
package com.spring.testlist.util;
import org.apache.commons.lang3.time.DateFormatUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
 
/**
 * 日期工具类, 继承org.apache.commons.lang.time.DateUtils类
 *
 * @author cui
 * @create 2018-10-26 15:30
 **/
public class DateUtil extends org.apache.commons.lang3.time.DateUtils{
 
    private static String[] parsePatterns = {
        "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
        "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
        "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
 
    /**
     * 得到当前日期字符串 格式(yyyy-MM-dd)
     */
    public static String getDate() {
      return getDate("yyyy-MM-dd");
    }
  /**
   * 得到当前日期字符串 格式(yyyyMMdd)
   */
  public static String getSizeDate() {
    return getDate("yyyyMMdd");
  }
 
    /**
     * 得到当前日期字符串 格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String getDate(String pattern) {
      return DateFormatUtils.format(new Date(), pattern);
    }
 
    /**
     * 得到日期字符串 默认格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(Date date, Object... pattern) {
      if (date == null) {
        return null;
      }
      String formatDate = null;
      if (pattern != null && pattern.length > 0) {
        formatDate = DateFormatUtils.format(date, pattern[0].toString());
      } else {
        formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
      }
      return formatDate;
    }
 
    /**
     * 得到日期时间字符串,转换格式(yyyy-MM-dd HH:mm:ss)
     */
    public static String formatDateTime(Date date) {
      return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }
 
    /**
     * 得到当前时间字符串 格式(HH:mm:ss)
     */
    public static String getTime() {
      return formatDate(new Date(), "HH:mm:ss");
    }
 
    /**
     * 得到当前日期和时间字符串 格式(yyyy-MM-dd HH:mm:ss)
     */
    public static String getDateTime() {
      return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
    }
 
    /**
     * 得到当前年份字符串 格式(yyyy)
     */
    public static String getYear() {
      return formatDate(new Date(), "yyyy");
    }
 
    /**
     * 得到当前月份字符串 格式(MM)
     */
    public static String getMonth() {
      return formatDate(new Date(), "MM");
    }
 
    /**
     * 得到当天字符串 格式(dd)
     */
    public static String getDay() {
      return formatDate(new Date(), "dd");
    }
 
    /**
     * 得到当前星期字符串 格式(E)星期几
     */
    public static String getWeek() {
      return formatDate(new Date(), "E");
    }
 
    /**
     * 日期型字符串转化为日期 格式
     * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
     * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm",
     * "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" }
     */
    public static Date parseDate(Object str) {
      if (str == null) {
        return null;
      }
      try {
        return parseDate(str.toString(), parsePatterns);
      } catch (ParseException e) {
        return null;
      }
    }
    /**
     * 获取过去的天数
     *
     * @param date
     * @return
     */
    public static long pastDays(Date date) {
 
      long t = System.currentTimeMillis()- date.getTime();
      return t / (24 * 60 * 60 * 1000);
    }
    /**
     * 获取过去的小时
     *
     * @param date
     * @return
     */
    public static long pastHour(Date date) {
      long t =System.currentTimeMillis() - date.getTime();
      return t / (60 * 60 * 1000);
    }
    /**
     * 获取过去的分钟
     *
     * @param date
     * @return
     */
    public static long pastMinutes(Date date) {
      long t = System.currentTimeMillis() - date.getTime();
      return t / (60 * 1000);
    }
    /**
     * 转换为时间(天,时:分:秒.毫秒)
     *
     * @param timeMillis
     * @return
     */
    public static String formatDateTime(long timeMillis) {
      long day = timeMillis / (24 * 60 * 60 * 1000);
      long hour = (timeMillis / (60 * 60 * 1000) - day * 24);
      long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60);
      long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
      long sss = (timeMillis - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - s * 1000);
      return (day > 0 ? day + "," : "") + hour + ":" + min + ":" + s + "." + sss;
    }
    /**
     * 获取两个日期之间的天数
     *
     * @param before
     * @param after
     * @return
     */
    public static double getDistanceOfTwoDate(Date before, Date after) {
      long beforeTime = before.getTime();
      long afterTime = after.getTime();
      return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
    }
    public static String getFirstDayOfMonth() {
      SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
      //获取当前月第一天:
      Calendar c = Calendar.getInstance();
      c.add(Calendar.MONTH, 0);
      c.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
      String first = format.format(c.getTime());
      return first;
    }
    /**
     * @param args
     * @throws ParseException
     */
    public static void main(String[] args) throws ParseException {
// System.out.println(formatDate(parseDate("2010/3/6")));
// System.out.println(getDate("yyyy年MM月dd日 E"));
// long time = new Date().getTime()-parseDate("2012-11-19").getTime();
// System.out.println(time/(24*60*60*1000));
      String sizeDate = formatDate(new Date(),"yyyyMMdd");
      System.out.println(sizeDate);
    }
}

到此就结束了,具体的要实现什么排序,根据示例自己脑补扩展就好了,例子中备注也已经标注。

在使用排序注意两个坑

1.要排序的字段为空的异常处理

2.要排序的字段相等的异常处理

补充知识:Java中的自然排序和比较器排序

写在前面的话:刚开始学习着两者排序时我也是一头雾水,虽然能写出来但是稀里糊涂,几时该用哪个排序一点想法都没有,后来经过研究这两者的作用点不同,自然排序作用在实体类上,而比较器排序作用在装实体类的集合上。

1、自然排序:java.lang.Comparable

Comparable 接口中只提供了一个方法: compareTo(Object obj) ,该方法的返回值是 int 。如果返回值为正数,则表示当前对象(调用该方法的对象)比 obj 对象“大”;反之“小”;如果为零的话,则表示两对象相等。

总结为一句话:实现Comparable,重写 compareTo方法

案列:以TreeMap为例,默认的升序,可以重写自然排序的方法改变原有排序

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public static void testComparable(){
    TreeMap<Car,Object> tmp = new TreeMap<Car,Object>();
    tmp.put(new Car(4), "肆");
    tmp.put(new Car(1), "壹");
    tmp.put(new Car(5), "伍");
    tmp.put(new Car(3), "三");
    tmp.put(new Car(2), "贰");
    System.out.println(tmp);
    //结果://{Car [price=5.0]=伍, Car [price=4.0]=肆, Car [price=3.0]=三, Car [price=2.0]=贰, Car [price=1.0]=壹}
  }
//自定义TreeMap排序方法  自然排序 
 
class Car implements Comparable<Car>{
  private double price;
  
  public double getPrice() {
    return price;
  }
 
  public void setPrice(double price) {
    this.price = price;
  }
 
  public Car(int price) {
    super();
    this.price = price;
  }
 
  @Override
  public int compareTo(Car o) {
    // TODO Auto-generated method stub
    if(this.price>o.getPrice()){
      return -1;//大的往前排
    }else if(this.price<o.getPrice()){
      return 1;//小的往后排
    }else{
      return 0;
    }
  }
 
  @Override
  public String toString() {
    return "Car [price=" + price + "]";
  }

2、比较器排序:java.util.Comparator

总结为一句话:实现Comparator 接口,重写compare方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void testComparator(){
    //HashMap<Integer,Object> hm = new HashMap<Integer,Object>();
    TreeMap<Integer,Object> tmp = new TreeMap<Integer,Object>(new MyComparatorBigtoSmall());
    tmp.put(4, "肆");
    tmp.put(1, "壹");
    tmp.put(5, "伍");
    tmp.put(3, "三");
    tmp.put(2, "贰");
    //System.out.println(tmp);//默认排序结果:{1=壹, 2=贰, 3=三, 4=肆, 5=伍}
    System.out.println(tmp);//修改为比较器排序(升序){5=伍, 4=肆, 3=三, 2=贰, 1=壹}
  }
 
//自定义TreeMap排序方法  比较器排序 
  class MyComparatorBigtoSmall implements Comparator<Integer>{
 
    @Override
    public int compare(Integer o1, Integer o2) {
      // TODO Auto-generated method stub
      return o2-o1;
    }
  }

以上这篇java 实现Comparable接口排序,升序、降序、倒叙就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/C1041067258/article/details/86578188