2016-12-22 6 views
1

Я пытаюсь сортировать длинные числа в ASC, но кажется, что сравнение неверно. Существует последовательность правильных цифр, но из 7-й цифры все это испортится. Может ли кто-нибудь посоветовать почему?Сортировка неверна при сравнении длинных значений

Классы:

public class MyTime { 

    private long timeInMicroSeconds; 

    public MyTime (long timeInMicroSeconds) { 
     this.timeInMicroSeconds = timeInMicroSeconds; 
    } 
} 

public class tester implements Comparator<MyTime> { 

     public int compare(MyTime o1, MyTime o2) { 
      return (int) ((-1) * (o2.getTimeInMicroSeconds() - o1.getTimeInMicroSeconds())); 
} 

}

Это основной тест с моими номерами:

MyTime t1 = new MyTime (1482072568710018L); 
    MyTime t2 = new MyTime (1482068966855246L); 
    MyTime t3 = new MyTime (1482068967752058L); 
    MyTime t4 = new MyTime (1482069164096129L); 
    MyTime t5 = new MyTime (1482072704590983L); 
    MyTime t6 = new MyTime (1482068963206124L); 
    MyTime t7 = new MyTime (1482069164097807L); 
    MyTime t8 = new MyTime (1482068962786004L); 
    MyTime t9 = new MyTime (1482069034105390L); 
    MyTime t10 = new MyTime (1482068979718112L); 
    MyTime t11 = new MyTime (1482068963143736L); 
    MyTime t12 = new MyTime (1482069164098280L); 
    MyTime t13 = new MyTime (1482069029615872L); 
    MyTime t14 = new MyTime (1482072704590408L); 



    List<MyTime > n = new ArrayList<MyTime >(); 
    n.add(t1); 
    n.add(t2); 
    n.add(t3); 
    n.add(t7); 
    n.add(t11); 
    n.add(t14); 
    n.add(t10); 
    n.add(t9); 
    n.add(t6); 
    n.add(t2); 
    n.add(t4); 
    n.add(t12); 
    n.add(t13); 
    n.add(t5); 
    n.add(t8); 



//RUNNING THE SORT 
    System.out.println("printing before : "); 
    for(int i = 0 ; i < n.size() ; i ++) 
    { 
     System.out.println(n.get(i).getTimeInMicroSeconds()); 
    } 

    Collections.sort(n, new tester()); 
    System.out.println("printing after : "); 
    for(int i = 0 ; i < n.size() ; i ++) 
    { 
     System.out.println(n.get(i).getTimeInMicroSeconds()); 
    } 

И это выход:

printing before : 
1482072568710018 
1482068966855246 
1482068967752058 
1482069164097807 
1482068963143736 
1482072704590408 
1482068979718112 
1482069034105390 
1482068963206124 
1482068966855246 
1482069164096129 
1482069164098280 
1482069029615872 
1482072704590983 
1482068962786004 


printing after : 
1482072568710018 
1482072704590408 
1482072704590983 
1482068962786004 
1482068963143736 
1482068963206124 
1482068966855246 
1482068966855246 
1482068967752058 
1482068979718112 
1482069029615872 
1482069034105390 
1482069164096129 
1482069164097807 
1482069164098280 

Вы можете см., что: 1482072568710018 < 1482072704590408 <1482072704590983> 1482068962786004

любой совет, что я сделал не так?

ответ

3

Зачем реализовать свое сравнение здесь? Существует уже «по умолчанию» способ сравнения с длинными значениями, а это Long.compare(). Так просто изменить способ вызвать этот статический метод:

public int compareTo(MyTime ...) { 
    return Long.compare(o1.get... 
} 
+3

Не нужно их укладывать. ['Long.compare (long, long)'] (https://docs.oracle.com/javase/7/docs/api/java/lang/Long.html#compare (long,% 20long)). –

+0

Я бы даже не привел в него 'Long.compareTo()': 'Long.compare' - правильный подход. Бокс их просто неэффективен, так как [они немедленно распаковываются] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/lang/Long.java# 1233). –

+0

Вы правы; имеет больше смысла. Обновлено так. – GhostCat

3

Проблема является приведение в

return (int) ((-1) * // ... 

в этот момент вы просто хобот верхние 4 байта от длинного получения значения случайным битом является индикатор знака.

Поэтому вы получаете случайное число.

Как другой уже говорилось лучше использовать

Long.compare() 

и если у вас есть обратный вид просто переключают положение сравниваемых чисел вместо делать * -1.

+1

«Поэтому вы получаете случайное число». Я бы не сказал «случайный», поскольку это явно не так; Я бы сказал, что вы в конечном итоге делаете бессмысленное сравнение. –

+0

спасибо большое .. исправлено и правильно работает – user1386966

+0

Вы имели в виду: «верхние 4 байта». «Int» - 4 байта, «long» - 8 байтов. – Andreas