java 【排序】異常:java.lang.IllegalArgumentException: Comparison method violates its general contract!
環境
java:1.7
前言
本來是不想寫這篇的,但是最近老報這個錯誤,一開始,我以為解決了,後來發現不是那麼回事
現在特意記錄下
我的排序程式碼
我先貼出完整的排序程式碼:
/**
* 支援兩個欄位排序
* @param result
* @param order
* @param orderType
* @param twoOrder 第二排序欄位
* @param twoType 第二排序順序
* @return
* @author yutao
* @date 2018年5月24日下午3:00:03
*/
public static List<Map<String, Object>> resultOrder (List<Map<String, Object>> result, String order, Integer orderType,
final String twoOrder, final Integer twoType){
if(result == null || orderType == null){
return result;
}
if(orderType != -1){
orderType = 1 ;
}
final String orderKey = order;
final Integer oType = orderType;
Collections.sort(result, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
Object obj1 = o1.get(orderKey);
Object obj2 = o2.get(orderKey);
return commonOrder(orderKey, oType, obj1, obj2, twoOrder, twoType);
}
});
return result;
}
/**
* 公共的排序部分
* @param orderKey
* @param oType
* @param obj1
* @param obj2
* @param twoOrder
* @param twoType
* @return
* @author yutao
* @date 2018年5月24日下午3:19:37
*/
public static Integer commonOrder(final String orderKey, final Integer oType, Object obj1, Object obj2, String twoOrder, Integer twoType) {
//重點注意
if(obj1 == null && obj2 == null){
return 0;
}
if (obj1 == null) {
if(oType < 0){
return -oType;
}
return oType;
}
if (obj2 == null) {
if(oType < 0){
return oType;
}
return -oType;
}
if(obj1 instanceof Date && obj2 instanceof Date){
//日期排序
Date date1 = (Date)obj1;
Date date2 = (Date)obj2;
return longCompare(oType, date1.getTime(), date2.getTime(), twoOrder, twoType);
}else if(obj1 instanceof String && obj2 instanceof String){
//字串排序
String str1 = obj1.toString();
String str2 = obj2.toString();
if(str1.compareTo(str2) < 0){
return -oType;
}else if(str1.compareTo(str2) == 0){
return 0;
}else if(str1.compareTo(str2) > 0){
return oType;
}
}else if((obj1 instanceof Double || obj1 instanceof Float) && (obj2 instanceof Double || obj2 instanceof Float)){
//浮點型排序
return doubleCompare(oType, obj1, obj2, twoOrder, twoType);
}else if((obj1 instanceof Long || obj1 instanceof Integer || obj1 instanceof Short || obj1 instanceof Byte) &&
(obj2 instanceof Long || obj2 instanceof Integer || obj2 instanceof Short || obj2 instanceof Byte)){
//整數型排序
return longCompare(oType, obj1, obj2, twoOrder, twoType);
}else if((obj1.getClass() != obj2.getClass()) && (obj1 instanceof Number && obj2 instanceof Number)){
//這種情況可能是,既有整數又有浮點數
return doubleCompare(oType, obj1, obj2, twoOrder, twoType);
}
return 0;
}
/**
* 整形比較大小
* @param oType
* @param obj1
* @param obj2
* @param twoOrder
* @param twoType
* @return
* @author yutao
* @date 2018年5月24日下午3:09:18
*/
private static int longCompare(final Integer oType, Object obj1, Object obj2, String twoOrder, Integer twoType) {
long d1 = Long.parseLong(obj1.toString());
long d2 = Long.parseLong(obj2.toString());
if(d1 < d2){
return -oType;
}else if(d1 == d2){
if(twoOrder != null && twoType != null){
//相等就使用第二欄位排序
return commonOrder(twoOrder, twoType, obj1, obj2, null, null);
}
//相同的是否進行互動
return 0;
}else if(d1 > d2){
return oType;
}
return 0;
}
/**
* 浮點型比較大小
* @param oType
* @param obj1
* @param obj2
* @return
* @author yutao
* @date 2018年5月24日下午3:09:41
*/
private static int doubleCompare(final Integer oType, Object obj1, Object obj2, String twoOrder, Integer twoType) {
double d1 = Double.parseDouble(obj1.toString());
double d2 = Double.parseDouble(obj2.toString());
if(d1 < d2){
return -oType;
}else if(d1 == d2){
if(twoOrder != null && twoType != null){
//相等就使用第二欄位排序
return commonOrder(twoOrder, twoType, obj1, obj2, null, null);
}
return 0;
}else if(d1 > d2){
return oType;
}
return 0;
}
分析
在JDK7以後,實現Comparable介面後,要滿足一下三個特性:
1) 自反性:x,y 的比較結果和 y,x 的比較結果相反。
2) 傳遞性:x>y,y>z,則 x>z。
3) 對稱性:x=y,則 x,z 比較結果和 y,z 比較結果相同。
而我的程式碼中,因為有物件屬性為null的判斷,所以有下面這樣的程式碼:
public static Integer commonOrder(final String orderKey, final Integer oType, Object obj1, Object obj2, String twoOrder, Integer twoType) {
if (obj1 == null) {
if(oType < 0){
return -oType;
}
return oType;
}
if (obj2 == null) {
if(oType < 0){
return oType;
}
return -oType;
}
// 以下程式碼省略。。。
這樣的話,是不滿足對稱性的;
因為必須完善為null
的情況:
public static Integer commonOrder(final String orderKey, final Integer oType, Object obj1, Object obj2, String twoOrder, Integer twoType) {
//重點注意
if(obj1 == null && obj2 == null){
return 0;
}
if (obj1 == null) {
if(oType < 0){
return -oType;
}
return oType;
}
if (obj2 == null) {
if(oType < 0){
return oType;
}
return -oType;
}
// 以下程式碼省略。。。
有了上面的程式碼,就滿足對稱性了。
相關推薦
java 【排序】異常:java.lang.IllegalArgumentException: Comparison method violates its general contract!
環境 java:1.7 前言 本來是不想寫這篇的,但是最近老報這個錯誤,一開始,我以為解決了,後來發現不是那麼回事 現在特意記錄下 我的排序程式碼 我先貼出完整的排序程式碼: /** * 支援兩個欄位排序 * @param result
java.lang.IllegalArgumentException: Comparison method violates its general contract!的解決方法
上午在敲程式碼時,對一個List集合進行排序,程式碼如下: Collections.sort(list2,new Comparator<Integer>()
java.lang.IllegalArgumentException: Comparison method violates its general contract!
背景 16號為了統一線上伺服器執行環境,將兩臺伺服器的Tomcat6+JDK6升級到Tomcat7+JDK7,本以為很簡單的事情,升級後自己驗證也沒問題,沒想到卻悲劇了。升級後,過了半小時運營就找過來反饋問題,部分角色無法登陸系統,由於異常日誌沒有輸出,沒有找
java-collections.sort異常Comparison method violates its general contract!
異常資訊 java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.util.TimSort.mergeHi(TimSort.java:868
排序:這個坑,你要注意:Comparison method violates its general contract!
解決方法如下: /** * 對比類:根據持有金額 */ private static class TenderCollectComparator implements Comparator<TenderCollect> { public int compa
集合排序中的 Comparison method violates its general contract 異常
異常資訊 java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.util.TimSort.mergeHi(TimSort.java:86
[Java]實現Comparable介面不嚴謹導致Comparison method violates its general contract!
/** * 已經將src陣列複製了一份到dest陣列 * low和high是mergesort在陣列中的下標 * off為low相對於下標0的偏移量 */ private static void mergeSort(Object[] src,
Android碰到 "Comparison method violates its general contract" 異常的解決方法
1.概述: 最近在對資訊進行排序時,做了一個簡單地比較器,當時在執行時並沒有報錯,但是,後臺資料重新整理時,我這邊就出了問題。在jdk1.6中,當我們比較的內容的值相同時,使用java自己的排序方法"Collections.sort()"是很正常的,可是到了jdk1.7,
這個坑,你要注意:Comparison method violates its general contract!
背景有部分業務需要進行排序,對比的物件是某實體裡的金額(double 型別),這樣,我們實現了自定義的比較類,結果執行一段時間之後報了錯誤:Comparison method violates its general contract! ,經過校驗,發現錯誤出現在自定義排序上
【Java工具推薦】Generator:Java程式碼生成工具
歡迎來到 Generator 寫這個程式碼生成器工具的想法源自2018年3月份,當時專案組剛完成一個Java Web專案的研發工作,在整個專案過程中耗費了不少的時間來構建SpringMVC的重複性程式碼和Mybatis的對映檔案,同時我也越來越覺得這些重複且難度不大的工作不
【深入Java虛擬機器】之一:Java記憶體區域與記憶體溢位
記憶體區域 Java虛擬機器在執行Java程式的過程中會把他所管理的記憶體劃分為若干個不同的資料區域。Java虛擬機器規範將JVM所管理的記憶體分為以下幾個執行時資料區:程式計數器、Java虛擬機器棧、本地方法棧、Java堆、方法區。下面詳細闡述各資料區所儲存的資料型
【我的Android進階之旅】Android 7.0報異常:java.lang.SecurityException: COLUMN_LOCAL_FILENAME is deprecated;
之前開發的一個和第三方合作的apk,在之前公司的 Android 5.1 系統的手錶上執行正常,今天在公司新開發的 Android 7.1系統的手錶上執行的時候,使用 DownloadManager 下載之後,查詢下載狀態的時候,報了異常 java.lan
【Spring錯誤筆記系列】自己new出來的bean中被@Autowired註解修飾的屬性報空指標異常:java.lang.NullPointException
自己new出來的bean中被@Autowired註解修飾的屬性報空指標異常 異常描述 原本我再測試RabbitMQ的傳送程式,裡面用到了一個AmqpTemplate介面,用了@Autowired註解。但是當我使用AmqpTemplate的conver
Springboot(Eureka)啟動異常:java.lang.NoSuchMethodError:【已解決】
根本原因是parent 中的version 版本過高 現階段預設版本2.0.1 將版本改為1.4.0之後啟動正常 <version>選項卡中改動 <parent> <groupId>org.springframework
【Hbase異常】windows 中使用hbase 異常:java.io.IOException: Could not locate executable null\bin\winutils.exe
平時一般是在windows環境下進行開發,在windows 環境下操作hbase可能會出現異常(java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoo
異常:java.lang.IllegalArgumentException: Control character in cookie value or attribute.
在服務器 jquery roc pro class leg val style mon 後臺提示: 嚴重: Error processing requestjava.lang.IllegalArgumentException: Control character in co
用eclipse部署tomcat時出現異常:java.lang.IllegalArgumentException
prope valid 路徑 存在 exist ali eclips tom tex 用eclipse部署tomcat時出現異常:java.lang.IllegalArgumentException: Invalid ‘log4jConfigLocation‘ parame
JSP-匯入taglib 出現classNotFound異常:java.lang.ClassNotFoundException: org.apache.taglibs.standard.tlv.Jst
案例 前端登入跳轉到指定jsp,報classNoFoundException,原因是頁面匯入 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 導致的 Caused by: java.lan
異常:java.lang.NumberFormatException: For input string:""
由於DAO層部分引數是整形,所以在前端傳來資料的時候把傳來的資料轉成了整形 Integer a = Integer.parseInt(request.getParameter("a")); 由於定義的驗空函式裡的引數是String 在驗空函式裡又把a變數轉為了String型 在前端提交資料的
java空指標異常:java.lang.NullPointException
一.什麼是java空指標異常 我們都知道java是沒有指標的,這裡說的"java指標"指的就是java的引用,我們不在這裡討論叫指標究竟合不合適,而只是針對這個異常本身進行分析。空指標就是空引用,java空指標異常就是引用本身為空,卻呼叫了方法,這個時候就會出現空指標異