以 "MMMyyyy" 为键对地图进行排序
Sort a map with "MMMyyyy" as key
我有一张地图,其键为 MMMyyyy 格式,我需要根据月份进行排序。
输入:
unsorted: {
"Dec2010": 1,
"Apr2010": 1,
"Feb2010": 0,
"Nov2010": 2,
"Mar2010": 0,
"Jun2010": 2,
"Sep2010": 1,
"May2010": 0,
"Oct2010": 1,
"Jul2010": 0,
"Aug2010": 0,
"Jan2010": 1
}
排序后应该是这样的:
sorted: {
"Jan2010": 1
"Feb2010": 0,
"Mar2010": 0,
"Apr2010": 1,
"May2010": 0,
"Jun2010": 2,
"Jul2010": 0,
"Aug2010": 0,
"Sep2010": 1,
"Oct2010": 1,
"Nov2010": 2,
"Dec2010": 1,
}
目前我正在使用树图,它按字母顺序对其进行排序,但我如何根据月份层次结构对其进行排序。
代码:
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);
System.out.println("\nSorted......");
Map<String, Integer> sorted = new TreeMap<>(unsorted);
for (Map.Entry<String, Integer> entry : sorted.entrySet()) {
System.out.println("Key : " + entry.getKey()
+ " Value : " + entry.getValue());
}
让我们尝试使用自定义比较器:
public class Main {
public static void main(String[] args) {
final SimpleDateFormat df = new SimpleDateFormat("MMMyyyy");
Map<String, Integer> map = new TreeMap<>(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
try {
return df.parse(s1).compareTo(df.parse(s2));
} catch (ParseException e) {
throw new RuntimeException("Bad date format");
}
};
});
map.put("Dec2011",1);
map.put("Jan2011",0);
map.put("Feb2011",1);
map.put("Mar2011",0);
map.put("Oct2011",1);
map.put("Sep2011",0);
for(Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
}
}
输出:
Jan2011 -> 0
Feb2011 -> 1
Mar2011 -> 0
Sep2011 -> 0
Oct2011 -> 1
Dec2011 -> 1
旧版日期时间 API(java.util
日期时间类型及其格式 API、SimpleDateFormat
)已过时且容易出错。建议完全停止使用,改用java.time
,modern date-time API*.
Java 东南 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);
}
}
输出:
{Jan2010=1, Feb2010=0, Mar2010=0, Apr2010=1, May2010=0, Jun2010=2, Jul2010=0, Aug2010=0, Sep2010=1, Oct2010=1, Nov2010=2, Dec2010=1}
从 Trail: Date Time[=55= 中了解有关 modern date-time API* 的更多信息].
Java 东南 9
Java SE 9 引入了 Map.ofEntries
,你可以用它来初始化你的 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);
}
}
使用单个语句进行排序和映射:
您可以利用强大的Stream
API(教程:1, 2)来完成您的工作。
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);
}
}
从 documentation 了解更多关于 Collectors#toMap
的信息。
* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用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 。
实际上,使用 TreeMap
和自定义 Comparator
答案很简单
Map<String, Integer> map = new HashMap<>();
map.put("Dec2010", 1);
map.put("Apr2010", 1);
map.put("Feb2010", 0);
map.put("Nov2010", 2);
map.put("Mar2010", 0);
map.put("Jun2010", 2);
map.put("Sep2010", 1);
map.put("May2010", 0);
map.put("Oct2010", 1);
map.put("Jul2010", 0);
map.put("Aug2010", 0);
map.put("Jan2010", 1);
Map<String, Integer> sortedMap = new TreeMap<>(Comparator.comparing(text -> YearMonth.parse(text, DateTimeFormatter.ofPattern("MMMyyyy", Locale.ENGLISH))));
sortedMap.putAll(map);
sortedMap.entrySet().forEach(System.out::println);
根据Arvind Kumar Avinash, here is an example using Eclipse Collections
的建议
这个例子非常相似,除了它有一个重载的构造函数接受源映射作为第二个参数
Map<String, Integer> sortedMap = new TreeSortedMap<>(
Comparator.comparing(text -> YearMonth.parse(text, DateTimeFormatter.ofPattern("MMMyyyy", Locale.ENGLISH))),
map
);
sortedMap.entrySet().forEach(System.out::println);
两者都导致
Jan2010=1
Feb2010=0
Mar2010=0
Apr2010=1
May2010=0
Jun2010=2
Jul2010=0
Aug2010=0
Sep2010=1
Oct2010=1
Nov2010=2
Dec2010=1
我有一张地图,其键为 MMMyyyy 格式,我需要根据月份进行排序。 输入:
unsorted: {
"Dec2010": 1,
"Apr2010": 1,
"Feb2010": 0,
"Nov2010": 2,
"Mar2010": 0,
"Jun2010": 2,
"Sep2010": 1,
"May2010": 0,
"Oct2010": 1,
"Jul2010": 0,
"Aug2010": 0,
"Jan2010": 1
}
排序后应该是这样的:
sorted: {
"Jan2010": 1
"Feb2010": 0,
"Mar2010": 0,
"Apr2010": 1,
"May2010": 0,
"Jun2010": 2,
"Jul2010": 0,
"Aug2010": 0,
"Sep2010": 1,
"Oct2010": 1,
"Nov2010": 2,
"Dec2010": 1,
}
目前我正在使用树图,它按字母顺序对其进行排序,但我如何根据月份层次结构对其进行排序。
代码:
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);
System.out.println("\nSorted......");
Map<String, Integer> sorted = new TreeMap<>(unsorted);
for (Map.Entry<String, Integer> entry : sorted.entrySet()) {
System.out.println("Key : " + entry.getKey()
+ " Value : " + entry.getValue());
}
让我们尝试使用自定义比较器:
public class Main {
public static void main(String[] args) {
final SimpleDateFormat df = new SimpleDateFormat("MMMyyyy");
Map<String, Integer> map = new TreeMap<>(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
try {
return df.parse(s1).compareTo(df.parse(s2));
} catch (ParseException e) {
throw new RuntimeException("Bad date format");
}
};
});
map.put("Dec2011",1);
map.put("Jan2011",0);
map.put("Feb2011",1);
map.put("Mar2011",0);
map.put("Oct2011",1);
map.put("Sep2011",0);
for(Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
}
}
输出:
Jan2011 -> 0
Feb2011 -> 1
Mar2011 -> 0
Sep2011 -> 0
Oct2011 -> 1
Dec2011 -> 1
旧版日期时间 API(java.util
日期时间类型及其格式 API、SimpleDateFormat
)已过时且容易出错。建议完全停止使用,改用java.time
,modern date-time API*.
Java 东南 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);
}
}
输出:
{Jan2010=1, Feb2010=0, Mar2010=0, Apr2010=1, May2010=0, Jun2010=2, Jul2010=0, Aug2010=0, Sep2010=1, Oct2010=1, Nov2010=2, Dec2010=1}
从 Trail: Date Time[=55= 中了解有关 modern date-time API* 的更多信息].
Java 东南 9
Java SE 9 引入了 Map.ofEntries
,你可以用它来初始化你的 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);
}
}
使用单个语句进行排序和映射:
您可以利用强大的Stream
API(教程:1, 2)来完成您的工作。
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);
}
}
从 documentation 了解更多关于 Collectors#toMap
的信息。
* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用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
实际上,使用 TreeMap
和自定义 Comparator
Map<String, Integer> map = new HashMap<>();
map.put("Dec2010", 1);
map.put("Apr2010", 1);
map.put("Feb2010", 0);
map.put("Nov2010", 2);
map.put("Mar2010", 0);
map.put("Jun2010", 2);
map.put("Sep2010", 1);
map.put("May2010", 0);
map.put("Oct2010", 1);
map.put("Jul2010", 0);
map.put("Aug2010", 0);
map.put("Jan2010", 1);
Map<String, Integer> sortedMap = new TreeMap<>(Comparator.comparing(text -> YearMonth.parse(text, DateTimeFormatter.ofPattern("MMMyyyy", Locale.ENGLISH))));
sortedMap.putAll(map);
sortedMap.entrySet().forEach(System.out::println);
根据Arvind Kumar Avinash, here is an example using Eclipse Collections
的建议这个例子非常相似,除了它有一个重载的构造函数接受源映射作为第二个参数
Map<String, Integer> sortedMap = new TreeSortedMap<>(
Comparator.comparing(text -> YearMonth.parse(text, DateTimeFormatter.ofPattern("MMMyyyy", Locale.ENGLISH))),
map
);
sortedMap.entrySet().forEach(System.out::println);
两者都导致
Jan2010=1
Feb2010=0
Mar2010=0
Apr2010=1
May2010=0
Jun2010=2
Jul2010=0
Aug2010=0
Sep2010=1
Oct2010=1
Nov2010=2
Dec2010=1