Java Comparator接口中compare方法使用

Java 专栏收录该内容
12 篇文章 0 订阅

经常忘记,记录一下.

  • 首先看一下部分排序源码
//----------------------------Collections.sort------------------------------------------
 public static <T> void sort(T[] a, Comparator<? super T> c) {
        if (c == null) {
            sort(a);
        } else {
            if (LegacyMergeSort.userRequested)
                legacyMergeSort(a, c);
            else
                TimSort.sort(a, 0, a.length, c, null, 0, 0);
        }
    }
//----------------------------legacyMergeSort ------------------------------------------
     private static <T> void legacyMergeSort(T[] a, Comparator<? super T> c) {
        T[] aux = a.clone();
        if (c==null)
            mergeSort(aux, a, 0, a.length, 0);
        else
            mergeSort(aux, a, 0, a.length, 0, c);
    }
//----------------------------mergeSort ------------------------------------------
       private static void mergeSort(Object[] src,
                                  Object[] dest,
                                  int low, int high, int off,
                                  Comparator c) {
        int length = high - low;
 
        // Insertion sort on smallest arrays
        if (length < INSERTIONSORT_THRESHOLD) {
            for (int i=low; i<high; i++)
                for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
                    swap(dest, j, j-1);
            return;
        }
 
        // Recursively sort halves of dest into src
        int destLow  = low;
        int destHigh = high;
        low  += off;
        high += off;
        int mid = (low + high) >>> 1;
        mergeSort(dest, src, low, mid, -off, c);
        mergeSort(dest, src, mid, high, -off, c);
 
        // If list is already sorted, just copy from src to dest.  This is an
        // optimization that results in faster sorts for nearly ordered lists.
        if (c.compare(src[mid-1], src[mid]) <= 0) {
           System.arraycopy(src, low, dest, destLow, length);
           return;
        }
 
        // Merge sorted halves (now in src) into dest
        for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
            if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
                dest[i] = src[p++];
            else
                dest[i] = src[q++];
        }
    }
//*****************************************重点*************************************************
 for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
                    swap(dest, j, j-1);

如果调用compare方法大于0,就把前一个数和后一个数交换,也就是把大的数放后面了,即所谓的升序。那么再想想看return arg0-arg1是不是返回的与这里正好匹配呢.
源码解析来自@shinerio

  • 这样我们就来实现自己的排序,根据Level与时间排序.
JavaBean
public class NotificationRecord {
	SimpleDateFormat format = new SimpleDateFormat("yyyy/M/d H:mm:ss SSS", Locale.CHINA);
	private int level;
	private long time;
	private String name;
	public int getLevel() {
		return level;
	}
	public void setLevel(int level) {
		this.level = level;
	}
	public long getTime() {
		return time;
	}
	public void setTime(long time) {
		this.time = time;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public NotificationRecord(int level, long time,String name) {
		super();
		this.level = level;
		this.time = time;
		this.name =name;
	}
	@Override
	public String toString() {
		return "NotificationRecord [level=" + level + ", time=" + format.format(time) + ", name=" + name + "]";
	}	
}
Comparator
public class NotifyComparator implements Comparator<NotificationRecord> {
	SimpleDateFormat format = new SimpleDateFormat("yyyy-M-d H:mm:ss SSS", Locale.CHINA);
	@Override
	public int compare(NotificationRecord arg0, NotificationRecord arg1) {
		int sort = 0;
		int level = arg1.getLevel() - arg0.getLevel();
		if (level != 0) {
			//降序
			sort = (level > 0) ? 2 : -1;
			//升序
//			sort = (level > 0) ? -2 : 1;
		} else {
			Date d1, d2;
			try {
				d1 = format.parse(format.format(arg0.getTime()));
				d2 = format.parse(format.format(arg1.getTime()));
			} catch (ParseException e) {
				return sort;
			}
			//降序
			sort = (d1.before(d2)) ? 1 : -2;
			//升序
//			return sort = (d1.before(d2)) ? -1 : 2;
		}
		return sort;
	}
}
SortTest
public class SortTest {
	public static void main(String[] args) {
		ArrayList<NotificationRecord> recordList = new ArrayList<NotificationRecord>() {
			private static final long serialVersionUID = 1L;
			{
				add(new NotificationRecord(1, 1557803095000L, "音乐"));
				add(new NotificationRecord(1, 1557903007000L, "音乐"));
				add(new NotificationRecord(2, 1557603116000L, "新闻"));
				add(new NotificationRecord(5, 1557503143001L, "升级"));
				add(new NotificationRecord(3, 1557403110000L, "电话"));
				add(new NotificationRecord(3, 1557303097000L, "电话"));
				add(new NotificationRecord(4, 1557203096006L, "支付"));
				add(new NotificationRecord(1, 1557103105000L, "音乐"));
				add(new NotificationRecord(0, 1558003108001L, "广告"));
				add(new NotificationRecord(4, 1558203105001L, "支付"));
				add(new NotificationRecord(5, 1558803108005L, "升级"));
				add(new NotificationRecord(2, 1557103108000L, "新闻"));
				add(new NotificationRecord(2, 1559003108000L, "新闻"));
				add(new NotificationRecord(0, 1557803118001L, "广告"));
			}
		};
		Collections.sort(recordList, new NotifyComparator());
		for (NotificationRecord nr : recordList) {
			System.out.println(nr.toString());
		}
	}
}
  • 结果输出
    在这里插入图片描述
    如果有错误还请指出.
  • 5
    点赞
  • 0
    评论
  • 6
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值