Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort keys which are date entries in a hashmap

I have a hashMap which has the following values as key value(sql date , integer) pairs:

a.put("31-05-2011",67);
a.put("01-06-2011",89);
a.put("10-06-2011",56);
a.put("25-05-2011",34);

when i try to sort the hashMap based on the keys using : Map modified_a=new TreeMap(a); and display the keys it is as follows :

01-06-2011,10-06-2011,25-05-2011, 31-05-2011

but I want the keys to be sorted as

31-05-2011,25-05-2011,01-06-2011 ,10-06-2011

I can see that the values are being sorted based on the first 2 digits( which is the date value) but I need the month value to also be considered and sort based on months first and then for each month sort the corresponding days. Any clues ??

like image 668
bhavya Avatar asked Jun 07 '11 06:06

bhavya


2 Answers

You can use like

Map<Date, Integer> m = new HashMap<Date, Integer>(); 

    DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");

    m.put(new java.sql.Date(dateFormat.parse("31-05-2011").getTime()),67);
    m.put(new java.sql.Date(dateFormat.parse("01-06-2011").getTime()),89);
    m.put(new java.sql.Date(dateFormat.parse("10-06-2011").getTime()),56);
    m.put(new java.sql.Date(dateFormat.parse("25-05-2011").getTime()),34);


    Map<Date, Integer> m1 = new TreeMap(m);
    DateFormat df = new SimpleDateFormat("dd/MM/yyyy");

    for (Map.Entry<Date, Integer> entry : m1.entrySet())
    {
        System.out.println(df.format(entry.getKey()));
    }
like image 109
jaychapani Avatar answered Oct 14 '22 17:10

jaychapani


The best solution IMO would be to use a different data type for the keys - a data type which actually represents a date, and which sorts in natural date order. Unless otherwise constrained, I'd use Joda Time's LocalDate type, which represents exactly what you want (just a date, not a date/time etc).

If you really want to use string keys but can change the format of them, you could use a yyyy-MM-dd format, which is naturally sortable.

Alternatively, you could pass in a Comparator<String> to the TreeMap constructor, where the comparator is one which parses two strings when it's asked to compare them, and performs the comparison based on the parsed year/month/day values. There isn't a constructor which takes both a custom comparator and an existing map though, so you'd need something like:

Map<String, Integer> modified = new TreeMap<String, Integer>(customComparator);
modified.putAll(a);

This approach will be relatively slow if you have a lot of data (due to the repeated parsing), and slightly fiddly to write - I'd use a more appropriate data type if you possibly can.

like image 30
Jon Skeet Avatar answered Oct 14 '22 18:10

Jon Skeet