欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java Comparator接口中compare方法使用

程序员文章站 2024-02-17 17:14:22
...

经常忘记,记录一下.

  • 首先看一下部分排序源码
//----------------------------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());
		}
	}
}
  • 结果输出
    Java Comparator接口中compare方法使用
    如果有错误还请指出.