The legacy date-time API (java.util
date-time types and their formatting API, SimpleDateFormat
) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time
, the modern date-time API*.
Java SE 8
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
Map<String, Integer> unsorted = new HashMap<>();
unsorted.put("Dec2010", 1);
unsorted.put("Apr2010", 1);
unsorted.put("Feb2010", 0);
unsorted.put("Nov2010", 2);
unsorted.put("Mar2010", 0);
unsorted.put("Jun2010", 2);
unsorted.put("Sep2010", 1);
unsorted.put("May2010", 0);
unsorted.put("Oct2010", 1);
unsorted.put("Jul2010", 0);
unsorted.put("Aug2010", 0);
unsorted.put("Jan2010", 1);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMMuuuu", Locale.ENGLISH);
Comparator<String> comparator = (s1, s2) -> YearMonth.parse(s1, dtf).compareTo(YearMonth.parse(s2, dtf));
Map<String, Integer> sorted = new TreeMap<>(comparator);
sorted.putAll(unsorted);
System.out.println(sorted);
}
}
Output:
{Jan2010=1, Feb2010=0, Mar2010=0, Apr2010=1, May2010=0, Jun2010=2, Jul2010=0, Aug2010=0, Sep2010=1, Oct2010=1, Nov2010=2, Dec2010=1}
Learn more about the the modern date-time API* from Trail: Date Time.
Java SE 9
Java SE 9 introduced Map.ofEntries
which you can use to initialize your Map<String, Integer> unsorted
.
import static java.util.Map.entry;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
Map<String, Integer> unsorted = Map.ofEntries(
entry("Dec2010", 1),
entry("Apr2010", 1),
entry("Feb2010", 0),
entry("Nov2010", 2),
entry("Mar2010", 0),
entry("Jun2010", 2),
entry("Sep2010", 1),
entry("May2010", 0),
entry("Oct2010", 1),
entry("Jul2010", 0),
entry("Aug2010", 0),
entry("Jan2010", 1)
);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMMuuuu", Locale.ENGLISH);
Comparator<String> comparator = (s1, s2) -> YearMonth.parse(s1, dtf).compareTo(YearMonth.parse(s2, dtf));
Map<String, Integer> sorted = new TreeMap<>(comparator);
sorted.putAll(unsorted);
System.out.println(sorted);
}
}
Sorting & mapping using a single statement:
You can make use of the powerful Stream
API (tutorials: 1, 2) to get your job done.
import static java.util.Map.entry;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Map<String, Integer> unsorted = Map.ofEntries(
entry("Dec2010", 1),
entry("Apr2010", 1),
entry("Feb2010", 0),
entry("Nov2010", 2),
entry("Mar2010", 0),
entry("Jun2010", 2),
entry("Sep2010", 1),
entry("May2010", 0),
entry("Oct2010", 1),
entry("Jul2010", 0),
entry("Aug2010", 0),
entry("Jan2010", 1)
);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMMuuuu", Locale.ENGLISH);
Map<String, Integer> sorted = unsorted
.entrySet()
.stream()
.collect(Collectors.toMap(
e -> YearMonth.parse(e.getKey(), dtf),
e -> e.getValue(),
(v1, v2) -> v1,
TreeMap::new
)) // Returns TreeMap<YearMonth, Integer>
.entrySet()
.stream()
.collect(Collectors.toMap(
e -> dtf.format(e.getKey()),
e -> e.getValue(),
(v1, v2) -> v1,
LinkedHashMap::new
));
System.out.println(sorted);
}
}
Learn more about Collectors#toMap
from the documentation.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
YearMonth
objects. Only when you need to give string output, format theYearMonth
into a string in the required format. – Uracil