2015-07-17 2 views
0

Когда я выполняю код ниже, я получаю вывод как [0, -2000000000, 2000000000].Сортировка с компаратором и массивами.asList()

import java.util.Arrays; 
import java.util.Comparator; 

public class SordidSort { 
public static void main(String args[]) { 
    Integer big = new Integer(2000000000); 
    Integer small = new Integer(-2000000000); 
    Integer zero = new Integer(0); 
    Integer[] arr = new Integer[] { big, small, zero }; 
    Arrays.sort(arr, new Comparator<Object>() { 
     public int compare(Object o1, Object o2) { 
      return ((Integer) o2).intValue() - ((Integer) o1).intValue(); 
     } 
    }); 
    System.out.println(Arrays.asList(arr)); 
    } 
} 

Как это отсортировано по номерам?

+1

Точно так, как вы это указали, с твистом, что 'int' не может содержать значение' (-) 4000000000', поэтому вы получаете переполнение. Попробуйте использовать меньшие числа или 'long'. – Keppil

+0

Возможный дубликат [Как правильно сравнить два целых числа в Java?] (Http://stackoverflow.com/questions/1514910/how-to-properly-compare-two-integers-in-java) – user902383

ответ

0

В ручной реализации компаратора есть некоторые тонкости. Вы только что нанесли удар по типу int. Намного сложнее сравнить два значения float или double. Если вы не используете -0.0, у вас могут быть 0.0 и -0.0 неправильно. И если вы не обрабатываете NaN, это может привести к катастрофе (случайный порядок после сортировки, сломанный TreeMap и т. Д.). К счастью, есть готовые статические методы с именем compare в каждом коробчатом типе: Integer.compare (начиная с Java 7), Double.compare, Float.compare и так далее. Используйте их, и у вас никогда не будет таких проблем.

Поскольку Java 8 реализации компараторов намного проще: у вас есть готовые вспомогательные методы, такие как Comparator.comparingInt:

Arrays.sort(arr, Comparator.comparingInt(o -> ((Integer)o).intValue())); 
1

Вместо

public int compare(Object o1, Object o2) { 
    return ((Integer) o2).intValue() - ((Integer) o1).intValue(); 
} 

Используйте следующие

public int compare(Object o1, Object o2) { 
    int x1 = ((Integer) o1).intValue(); 
    int x2 = ((Integer) o2).intValue(); 
    if (x1 < x2) { 
     return -1; 
    } else if (x1 == x2) { 
     return 0; 
    } else { 
     return 1; 
    } 
} 

Ваш код может генерировать переполнение. Когда происходит переполнение, вы можете получить странный порядок.

+0

Как насчет ((Integer) o1) .compareTo ((Integer) o2)? – rob

+0

На самом деле совсем не обязательно использовать компаратор. Это естественный порядок Integer. Это только для того, чтобы уделить особое внимание тому, где проблема связана с int-int –

0

Изменить код, как следовать ::

import java.util.Arrays; 
import java.util.Comparator; 

public class SordidSort { 

    public static void main(String args[]) { 
     Integer big = new Integer(2000000000); 
     Integer small = new Integer(-2000000000); 
     Integer zero = new Integer(0); 
     Integer[] arr = new Integer[] { big, small, zero }; 
     Arrays.sort(arr, new Comparator<Object>() { 
      public int compare(Object o1, Object o2) { 

       int o1Val = ((Integer) o1).intValue(); 
       int o2Val = ((Integer) o2).intValue(); 

       if(o1Val > o2Val){ 
        return 1; 
       } else if(o1Val == o2Val){ 
        return 0; 
       }else{ 
        return -1; 
       } 
      } 
     }); 
     System.out.println(Arrays.asList(arr)); 

    } 
} 
0

Вы можете объявить компаратор, как new Comparator<Integer>(), так что вы передаете Integer S к вашей функции сравнения, вы можете воспользоваться методом Integer.compareTo

public static void main(String args[]) { 
    Integer big = new Integer(2000000000); 
    Integer small = new Integer(-2000000000); 
    Integer zero = new Integer(0); 
    Integer[] arr = new Integer[] { big, small, zero }; 
    Arrays.sort(arr, new Comparator<Integer>() { 
     @Override 
     public int compare(Integer o1, Integer o2) { 
     return o1.compareTo(o2); 
     } 
    }); 
    System.out.println(Arrays.asList(arr)); 
    } 
Смежные вопросы