Sort keys that are hash date entries

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

 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 a hash map based on keys using: Map modified_a = new TreeMap (a); and display the following keys:

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

but I want the keys to be sorted like

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

I see that the values ​​are sorted based on the first two digits (this is a date value), but I need the month value to be taken into account and sorted by month first, and then sort the corresponding days for each month. Any hints

+3
source share
6 answers

You can use as

 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())); } 
+5
source

The best IMO solution would be to use a different data type for the keys - a data type that actually represents a date and that is sorted in a natural date order. Unless otherwise specified, I would use the Joda Time 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 you can change their format, you can use the yyyy-MM-dd format, which is naturally sorted.

Alternatively, you can pass the Comparator<String> constructor to the TreeMap constructor, where the comparator is the one that parses the two strings when it asks them to compare, and performs a comparison based on the parsing values ​​of year / month / day, There is no constructor that uses both its own comparator and the existing map, so you 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 re-parsing) and it is a little difficult to write - I would use a more suitable data type if possible.

+9
source

I had a requirement to cancel the sorting of dates (the most recent date is the first). I did this using the following code:

 Map<Date, Integer> dateMap = new TreeMap<Date, Integer>(new Comparator<Date>() { public int compare(Date date1, Date date2) { return date2.compareTo(date1); } }); 

Calling dateMap.keySet() will result in a Set with keys in which the most recent dates will be returned first.

+4
source

You need to pass the custom comparator to the TreeMap constructor, which will compare your keys as dates instead of strings (or use java.util.Date as a key, in which case this will happen out of the box, since the date implements Comparable).

+2
source

Create Comparator:

 public class DateComparator implements Comparator<Date> { public int compare(Date date1, Date date2) { return date1.compareTo(date2); } } 

And use a comparator with TreeMap

 Map<Date, Integer> comparedDates = new TreeMap<Date, Integer>(new DateComparator()); // here fill you <Date, Integer> map like: comparedDates.put(new Date(System.currentTimeMillis()), 123); 

All dates in your card will be sorted.

+1
source

You can use TreeMap instead of HashMap and create a map with a custom Comparator that provides sorting.

Here's a draft of an anonymous comparator (which doesn't parse a string into a comparable date object):

 new Comparator<String>() { @Override public int compare(String date1, String date2) { // skipping tests! Assuming, all date are well formatted String[] parts1 = date1.split("-"); String[] parts2 = date2.split("-"); String reordered1 = parts1[2] + parts1[1] + parts1[0]; String reordered2 = parts2[2] + parts2[1] + parts2[0]; return reordered1.compareTo(reordered2); } } 
0
source

All Articles