Метод сравнения нарушает свой генеральный контракт на некоторых устройствах Android

#java #android

Вопрос:

У меня проблема с моим длинным компаратором, поле времени-это метка времени unix, и по какой-то причине на паре устройств Android я получаю следующее исключение:

 java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:899)
at java.util.TimSort.mergeAt(TimSort.java:516)
at java.util.TimSort.mergeForceCollapse(TimSort.java:457)
at java.util.TimSort.sort(TimSort.java:254)
at java.util.Arrays.sort(Arrays.java:1492)
at java.util.ArrayList.sort(ArrayList.java:1470)
at java.util.Collections.sort(Collections.java:206)
 

Код:

 public class SortByTime implements Comparator<JniChatItem> {
        @Override
        public int compare(JniChatItem item, JniChatItem item2) {
            return (int) (item.time - item2.time);
        }
}


public ArrayList<JniChatItem> getLastItemsOfChatsN(int itemCount) {
        ArrayList<JniChatItem> chatItemsList = new ArrayList<>();

        if (JniChatManager.getChatState() == ChatState.NEW_CHAT) {
            List<String> chatIds = getAllChatIds();
            chatItemsList.addAll(getLastItemsByChatsIds(chatIds, 1));

            Collections.sort(chatItemsList, new SortByTime());
            if (chatItemsList.size() > itemCount) {
                chatItemsList.subList(0, itemCount - 1);
            }
         }
         return chatItemsList;
}
 

Обновление: Я только что понял, что, возможно, из-за того, что это два длинных значения, они могут быть неправильно переведены в int, поэтому они могут быть слишком длинными. Я собираюсь переключиться на Long.comapare и проверить, исчезло ли исключение

Комментарии:

1. Ты на правильном пути. Простое использование вычитания двух long значений и приведение результата к int не дает действительного компаратора long значений. Вычитание даже не работает для int значений: Integer.compare(Integer.MAX_VALUE, Integer.MIN_VALUE) результат 1 (MAX_VALUE больше, чем MIN_VALUE), но из-за переполнения Integer.MAX_VALUE-Integer.MIN_VALUE целых чисел дает -1 (что означает, что MAX_VALUE меньше, чем MIN_VALUE)