Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to prioritize certain Strings while sorting a Map

I'd like to sort a map with strings, so that certain strings are prioritized and the rest is ordered as usual.

Like this:

"Dan",   "value"  //priority 1
"Eric",  "value"  //priority 2
"Ann",   "value"  //priority 3
"Bella", "value"  //no priority
"Chris", "value"  //no priority

Just like in this question.

I'm using a TreeMap and my current compare method looks like this:

public int compare(String o1, String o2) {
    if (o1.equals(o2)) return 0;
    if (o1.equals("Dan")) return -1;
    if (o2.equals("Dan")) return 1;
    if (o1.equals("Eric")) return -1;
    if (o2.equals("Eric")) return 1;
    if (o1.equals("Ann")) return -1;
    if (o2.equals("Ann")) return 1;
    else return o1.compareTo(o2);
}

As you can see, this gets quite cumbersome with more prioritized Strings.

Is there a better way to do this?


Solution (thanks to amit for the idea): Use a 2nd map to store the priorities:

TreeMap<String, Integer> prio = new TreeMap<>();
prio.put("Dan", 1);
prio.put("Eric", 2);
prio.put("Ann", 3);

comparator = new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        if (prio.containsKey(o1)) {
            if (prio.containsKey(o2)) {
                return prio.get(o1).compareTo(prio.get(o2));
            } else return -1;
        } else if (prio.containsKey(o2)) {
            return 1;
        } else return o1.compareTo(o2);
    }
};
like image 540
Robin Hartmann Avatar asked Oct 19 '22 19:10

Robin Hartmann


1 Answers

Use a 2nd map:

Map<String,Integer> prio where the value is the priority of each string.

In your comparator - first compare according to prio.get(o1).compareTo(prio.get(o2))1, and only if the result is 0, fall back to regular String's compareTo().

It is important that prio does not change after your map is created, otherwise your map will be a complete chaos without an ability to find and insert elements properly.


(1) Make sure both elements exist first in prio, and if one does not - resolve.

like image 104
amit Avatar answered Oct 22 '22 09:10

amit