Вопрос

У меня есть класс, который я упростил до этого:

final class Thing {
    private final int value;
    public Thing(int value) {
        this.value = value;
    }
    public int getValue() {
        return value;
    }
    @Override public String toString() {
        return Integer.toString(value);
    }
}

Я хочу отсортировать массив этой вещи.Итак, я создал простой копмаратор:

private static final Comparator<Thing> reverse = new Comparator<Thing>() {
    public int compare(Thing a, Thing b) {
        return a.getValue() - b.getValue();
    }
};

Затем я использую форму с двумя аргументами Arrays.sort.

Это отлично работает для моих тестовых случаев, но иногда все идет наперекосяк, когда массив заканчивается в странном, но повторяемом порядке.Как это может быть?

Это было полезно?

Решение

Переполнение целых чисел... или, точнее, недостаточный поток.

Вместо этого выполните явное сравнение:

private static final Comparator<Thing> reverse = new Comparator<Thing>() {
    public int compare(Thing a, Thing b) {
      int av = a.getValue(), bv = b.getValue();
      return (av == bv) ? 0 : ((av < bv) ? -1 : +1);
    }
};

Использование вычитания подойдет, если вы уверены, что разница не будет "оборачиваться".Например, когда значения, о которых идет речь, должны быть неотрицательными.

Другие советы

Вы не можете использовать минус для создания сравнения.Вы переполнитесь, когда абсолютная разница превысит Integer.MAX_VALUE.

Вместо этого используйте этот алгоритм:

int compareInts( int x, int y ) {
  if ( x < y ) return -1;
  if ( x > y ) return 1;
  return 0;
}

Мне хотелось бы иметь эту функцию в библиотеке для таких целей.

попробуй

System.out.println(Integer.MAX_Value - Integer.MIN_VALUE);

Это должно возвращать положительное число как MAX_VALUE > MIN_VALUE, но вместо этого выводит значение -1

При сравнении примитивов Java желательно преобразовать их в их объектные аналоги и полагаться на их compareTo() методы.

В этом случае вы можете сделать:

return Integer.valueOf(a.getValue()).compareTo(b.getValue())

Если вы сомневаетесь, используйте хорошо протестированную библиотеку.

Какие цифры вы туда вбрасываете?Если ваши числа достаточно велики, вы могли бы использовать МИНИМАЛЬНЫЕ / максимальные значения для целых чисел и в итоге получить беспорядок.

Если значение a очень отрицательное, а значение b очень положительное, ваш ответ будет очень неправильным.

IIRC, Int overflow бесшумно оборачивается в JVM

-- МаркусК

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top