0

I know similar questions have been asked before but I have a specific problem which I can't get my head wrong.

I want to sort a map by days of the week where days of the week are keys of the map. How do you compare strings which don't have natural order in compare method? Map at the end of the sort should be: Mon, Tue, Wed, Thur.

Here is my code so far but I am stuck at compare method.

    class OpeningTimes {

       private String openingTime;
       private String closingTime;
       public String getOpeningTime() {
           return openingTime;
       }
       public void setOpeningTime(String openingTime) {
           this.openingTime = openingTime;
       }
       public String getClosingTime() {
           return closingTime;
       }
       public void setClosingTime(String closingTime) {
           this.closingTime = closingTime;
       }

       @Override
       public String toString() {
           return new StringBuilder( "Opening Times: " + this.openingTime + " Closing Times: " + this.closingTime).toString();
       }
   }

Comparator:

class OpeningTimesComparator implements Comparator<Map.Entry<String, OpeningTimes>>{

   @Override
   public int compare(Entry<String, OpeningTimes> o1, Entry<String, OpeningTimes> o2) {
       return 0; // what is the logic?
   }}

Runner:

public class TestClass {

    public static void main(String[] args) {

        Map<String, OpeningTimes> openingTimesMap = new TreeMap<String, OpeningTimes>();

        OpeningTimes openTime1 = new OpeningTimes();
        openTime1.setOpeningTime("9PM");
        openTime1.setClosingTime("10PM");

        OpeningTimes openTime2 = new OpeningTimes();
        openTime2.setOpeningTime("11PM");
        openTime2.setClosingTime("9PM");

        OpeningTimes openTime3 = new OpeningTimes();
        openTime3.setOpeningTime("13PM");
        openTime3.setClosingTime("14PM");

        OpeningTimes openTime4 = new OpeningTimes();
        openTime4.setOpeningTime("15PM");
        openTime4.setClosingTime("13PM");

        openingTimesMap.put("Tue", openTime2);
        openingTimesMap.put("Thu", openTime4);
        openingTimesMap.put("Mon", openTime1);
        openingTimesMap.put("Wed", openTime3);


        for (Entry<String, OpeningTimes> openingTimesSingle : openingTimesMap.entrySet()) {
            System.out.println("Key: " + openingTimesSingle.getKey() + " Value: " + openingTimesMap.get(openingTimesSingle.getKey()));
        }

        List<Map.Entry<String, OpeningTimes>> list = new ArrayList<Map.Entry<String, OpeningTimes>>(openingTimesMap.entrySet());

        Collections.sort(list, new OpeningTimesComparator());

        for (Entry<String, OpeningTimes> openingTimesSingle : openingTimesMap.entrySet()) {
            System.out.println("Key: " + openingTimesSingle.getKey() + " Value: " + openingTimesMap.get(openingTimesSingle.getKey()));
        }
    }
}

Thanks in advance

1
  • 4
    Have a look at Enums. Commented Feb 16, 2015 at 17:50

1 Answer 1

4

Enum would be a good solution if not you have to use some other static map containing your custom order values.

Define an enum like this

enum Week{
  SUN,MON,TUE,WED,THU,FRI,SAT   
}

Create an instance of EnumMap and add entries and when you iterate over the keySet, entries will be retrieved in their order mentioned in enum

    Map<Week, String> map = new EnumMap<Week, String>(Week.class);

        map.put(Week.WED, "Wednesday");
        map.put(Week.SUN, "Sunday");
        map.put(Week.MON, "Monday");
        map.put(Week.THU, "Thursday");
        map.put(Week.SAT, "Saturday");
        map.put(Week.FRI, "Friday");
        map.put(Week.TUE, "Tuesday");


        for(Week week : map.keySet()){
            System.out.println(week + " -- " +map.get(week));
        }

Output :

SUN -- Sunday
MON -- Monday
TUE -- Tuesday
WED -- Wednesday
THU -- Thursday
FRI -- Friday
SAT -- Saturday

The same order which I defined in my enum. Of course, EnumMap is useful and efficient only when you have a bounded range of keys in your Map, like days in a week in your case. Hope this helps :)

Option 2 :-

This one works on the assumption that the inputKeys are absolutely managed by you. Be Careful with this as it might give you NPE in case a mapping does not exist for a given key.

private static Map<String,Integer> orderMappings = new HashMap<>();

    static{
        orderMappings.put("Sunday", 1);
        orderMappings.put("Monday", 2);
        orderMappings.put("Tuesday", 3);
        orderMappings.put("Wednesday", 4);
        orderMappings.put("Thursday", 5);
        orderMappings.put("Friday", 6);
        orderMappings.put("Saturday", 7);
    }

    class OrderComparator implements Comparator<String>{

        @Override
        public int compare(String key1, String key2) {
            int p1 = orderMappings.get(key1);
            int p2 =  orderMappings.get(key2);
            return p1-p2;
        }

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

3 Comments

If you find my answer useful, up-vote and accept so that others will find it resolved :)
This is a good workaround +1 but Lets assume I have to use comparator?
@webDeveloper, I've updated my answer but I still believe Option 1 is the best option for your case :)

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.