Sathesh S
Sathesh S

Reputation: 1323

Facing issue in Comparator<> in Collections.sort

Hi Below is my sample java code. the same logic i want to use in my application.

/*Bean Class*/
public class TestingBean {
private Integer intOne;
private Integer intTwo;
//getters and setters
}

/**Main Class*/
public class FilterTesting {
public static void main(String[] args) {
    validateFilter();
}

public static void validateFilter() {
    List<TestingBean> testBeanList=new ArrayList<TestingBean>();

    TestingBean testingBean=new TestingBean();
    testingBean.setIntOne(1);
    testingBean.setIntTwo(1003);
    testBeanList.add(testingBean);

    TestingBean testingBean2=new TestingBean();
    testingBean2.setIntOne(2);
    testingBean2.setIntTwo(2002);
    testBeanList.add(testingBean2);

    TestingBean testingBean3=new TestingBean();
    testingBean3.setIntOne(null);
    testingBean3.setIntTwo(1);
    testBeanList.add(testingBean3);

    Collections.sort(testBeanList,
            new Comparator<TestingBean>() {
                @Override
                public int compare(final TestingBean obj1,
                        final TestingBean obj2) {
                    if(obj1.getIntOne()==null || obj2.getIntOne()==null){
                        return obj1.getIntTwo().compareTo(obj2.getIntTwo());
                    }
                    else{
                        return obj1.getIntOne().compareTo(obj2.getIntOne());
                    }
                }
            });
    for (TestingBean testBean : testBeanList) {
        System.out.println(testBean.getIntOne()+" : "+testBean.getIntTwo());
    }

}
}

When i run this code i'm get the output as
null : 1
1 : 1003
2 : 2002
But my requirment is the output should be
1 : 1003
2 : 2002
null : 1
first the object should be sorted with intOne, if intOne is null the it should sorted using intTwo. Thanks in Advance.

Upvotes: 1

Views: 69

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

This code checks intOne for null, and jumps to comparing intTwos as soon as any of the two intOnes is detected to be null:

if(obj1.getIntOne()==null || obj2.getIntOne()==null){
    return obj1.getIntTwo().compareTo(obj2.getIntTwo());
}

This produces the effect that you see. If you would like to have the effect that you describe, change the code as follows:

if(obj1.getIntOne()==null && obj2.getIntOne()==null) {
    return obj1.getIntTwo().compareTo(obj2.getIntTwo());
} else if(obj1.getIntOne()==null && obj2.getIntOne()!=null) {
    // Null is greater than any non-null number
    return 1;
} else if(obj1.getIntOne()!=null && obj2.getIntOne()==null) {
    // Non-null is smaller than null
    return -1;
} else {
    return obj1.getIntOne().compareTo(obj2.getIntOne());
}

This change uses intTwos only when both intOnes are null. If only one of them is null, the value of null is interpreted as a very large number.

Upvotes: 4

Related Questions