1

I am trying to sort an ArrayList<String> using custom Comparator. My requirement is that XX String should be the first String, others should follow natural ordering.

I need : [XX, XX, 1, 5, 9, A, D, G, Q, Z]
What I am getting is [1, 5, 9, A, D, G, Q, Z, XX, XX]

Following is my code:

public class Test {
    public static void main(String[] args) 
    {
        List<String> list = new ArrayList<String>();
        list.add("Z");
        list.add("5");
        list.add("D");
        list.add("G");
        list.add("XX");     
        list.add("9");
        list.add("Q");
        list.add("XX");
        list.add("1");
        list.add("A");      
        Collections.sort(list, new CustomComparator());     
        System.out.println(list);       
    }
}
class CustomComparator implements Comparator<String>
{
    @Override
    public int compare(String o1, String o2) {      
        if(o2.equals("XX")) {
            return -1;
        }       
        return o1.compareTo(o2);
    }   
}

EDIT: if i change comparator logic to:

@Override
    public int compare(String o1, String o2) {      
        if(o2.equals("XX")) {
            return 1;
        }       
        return o1.compareTo(o2);
    }

I am getting :

[1, XX, 9, A, Q, XX, 5, D, G, Z]

Please let me know how to proceed. Thanks in advance.

2 Answers 2

2

Use this comparator implementation:

@Override
public int compare(String o1, String o2) {      
    if(o2.equals("XX")) {
        return o1.equals("XX") ? 0 : 1;
    } else if (o1.equals("XX")) {
        return -1;
    }
    return o1.compareTo(o2);
}  

Reason: Beyond the question when to use -1 or 1 it is important to guarantee a clear order for all possible tuples of o1 and o2, see javadoc:

[...] The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y. (This implies that compare(x, y) must throw an exception if and only if compare(y, x) throws an exception.)

The implementor must also ensure that the relation is transitive: ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0. [...]

Sign up to request clarification or add additional context in comments.

2 Comments

congratulations, your solution is only valid one
@nikis Thank you, I am used to such comparators because my employer often ask for exotic and overly complex comparison strategies, this here is just very simplified ;-)
1

Concise way to write the method:

public int compare(String o1, String o2) {
    if (o1.equals(o2)) return 0;
    if (o1.equals("XX")) return -1;
    return (o2.equals("XX")) ? 1 : o1.compareTo(o2);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.