user261002
user261002

Reputation: 2252

How to sort a java list against a custom order

I am trying to sort a list against a custom order, I have already followed the stackOverflow link. The custom order must be as followed : "ST, SIT, JDC" which has been done with an array list in customOrder. and a data comming from database must be shown in a list following the above order, but the problem is that this is only work if the data from the database match exactly to this list, like if I have an exact word of "ST" or "SIT" then it do the job. but the data that I am getting from the database looks like this :

ST1,ST2,ST3, SIT1,SIT2, JDC Release, JDC Stop, JDC 10

this code doesnt work for my data, there is no error in the result, but it doesnt sort the data at all.

here is the code :

List<Environment> environments = environmentDAO.getAll(); 
final List<String> customOrder = Arrays.asList("ST", "SIT", "JDC");

    Collections.sort(environments, new Comparator<Environment>() {

        @Override
        public int compare(final Environment o1, final Environment o2) {

            Integer firstValue = Integer.valueOf(customOrder.indexOf(o1.getAcronym()));
            Integer secondValue = Integer.valueOf(customOrder.indexOf(o2.getAcronym()));

            int comparedTo = firstValue.compareTo(secondValue);

            return comparedTo;
        }
    });

Upvotes: 0

Views: 2703

Answers (1)

NeplatnyUdaj
NeplatnyUdaj

Reputation: 6242

The problem is, that you don't define all of the possibilities in the customOrder list.

List.indexOf will return -1 for elements which are not found and in your case it's everything, so nothing gets sorted

So you need for example to assume that customOrder is only a list of prefixes. Is that what you want? In that case, you will need to find indices of the first match and also track the remainders in case both compared Strings have the same prefix:

    @Override
    public int compare(final Environment o1, final Environment o2) {
        int order1=-1;
        int order2=-1;
        String remainder1="";
        String remainder2="";
        for (String prefix: customOrder){
            if (o1.getAcronym().startsWith(prefix)){
                order1=customOrder.indexOf(prefix);
                remainder1=o1.getAcronym().substring(prefix.length());
            }
            if (o2.getAcronym().startsWith(prefix)){
                order2=customOrder.indexOf(prefix);
                remainder2=o2.getAcronym().substring(prefix.length());
            }
        }
        if (order1==order2){
            return remainder1.compareTo(remainder2);
        }
        else{
            return order1-order2;
        }
    }

But there will be some edge cases like overlapping prefixes etc. Anyway I've tried this code and it works on your data.

Upvotes: 2

Related Questions