0

When I execute below code, I am getting output as [0, -2000000000, 2000000000].

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));
    }
}

How it sorted the numbers?

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
Babanna Duggani
  • 737
  • 2
  • 12
  • 34
  • 1
    Exactly the way you specify it to do, with the twist that an `int` can't hold a value of `(-)4000000000`, so you get an overflow. Try using smaller numbers, or a `long`. – Keppil Jul 17 '15 at 09:12
  • possible duplicate of [How to properly compare two Integers in Java?](http://stackoverflow.com/questions/1514910/how-to-properly-compare-two-integers-in-java) – user902383 Jul 17 '15 at 09:48

4 Answers4

1

Instead of

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

Use the following

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;
    }
}

Your code can generate an overflow. When an overflow is generated you can obtain strange order.

Davide Lorenzo MARINO
  • 26,420
  • 4
  • 39
  • 56
0

There are some subtleties in manual implementation of comparator. You've just hit some regarding the int type. It's much more difficult to compare two float or double values correctly. If you don't handle -0.0 you may have 0.0 and -0.0 misordered. And if you don't handle NaN, it may lead to disaster (random order after sorting, broken TreeMap, etc.). Luckily there are ready static methods named compare in every boxed type: Integer.compare (since Java 7), Double.compare, Float.compare and so on. Use them, and you will never have such problems.

Since Java 8 implementing comparators is much simpler: you have ready helper methods like Comparator.comparingInt:

Arrays.sort(arr, Comparator.comparingInt(o -> ((Integer)o).intValue()));
Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
0

Change your code as follow ::

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));

    }
}
Kamal Pundir
  • 287
  • 4
  • 13
0

You could declare your Comparator as new Comparator<Integer>() so that you are passing Integers to your compare function, you can then benefit from the Integer.compareTo method

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));
  }
rob
  • 1,286
  • 11
  • 12