【发布时间】:2019-09-03 09:17:25
【问题描述】:
基本上,我想要实现的是按降序对最终地图进行排序。 (最新日期在地图的开头)。
我有以下方法,它将 DtObjects 的 ArrayList 作为参数和静态鉴别器字符串:
public static <T> Map<T, List<String>> groupTimePeriods(List<DtObject> timePeriods, String groupProperty)
{
Map<T, List<String>> groupedTimePeriods = new TreeMap<>();
if (timePeriods == null)
{
return groupedTimePeriods;
}
for (DtObject timePeriod : timePeriods)
{
GWT.log(groupedTimePeriods.toString());
T groupPropertyValue = timePeriod.<T> getProperty(groupProperty);
if (groupPropertyValue != null)
{
List<String> group = groupedTimePeriods.get(groupPropertyValue);
if (group == null)
{
groupedTimePeriods.put(groupPropertyValue, group = new ArrayList<>());
}
Long startTime = timePeriod.getProperty(Constants.TimePeriod.START_TIME);
Long endTime = timePeriod.getProperty(Constants.TimePeriod.END_TIME);
if (startTime != null || endTime != null)
{
group.add(formatTimePeriod(startTime, endTime));
}
}
}
return groupedTimePeriods;
}
我知道 DtObject 可能真的很复杂,但这里我只需要一个简单的 Date 对象
T groupPropertyValue = timePeriod.<T> getProperty(groupProperty);
返回日期。
例如,当我将日期按升序排列时,它看起来很好,没有混乱
ConsoleLogger.java:32 {}
ConsoleLogger.java:32 {Mon Sep 02 00:00:00 GMT+500 2019=[]}
ConsoleLogger.java:32 {Mon Sep 02 00:00:00 GMT+500 2019=[1:00-2:00]}
ConsoleLogger.java:32 {Mon Sep 02 00:00:00 GMT+500 2019=[1:00-2:00], Wed Sep 04 00:00:00 GMT+500 2019=[]}
ConsoleLogger.java:32 {Mon Sep 02 00:00:00 GMT+500 2019=[1:00-2:00], Wed Sep 04 00:00:00 GMT+500 2019=[], Fri Sep 06 00:00:00 GMT+500 2019=[]}
ConsoleLogger.java:32 {Mon Sep 02 00:00:00 GMT+500 2019=[1:00-2:00], Wed Sep 04 00:00:00 GMT+500 2019=[], Fri Sep 06 00:00:00 GMT+500 2019=[], Sat Sep 14 00:00:00 GMT+500 2019=[]}
ConsoleLogger.java:32 {Mon Sep 02 00:00:00 GMT+500 2019=[1:00-2:00], Wed Sep 04 00:00:00 GMT+500 2019=[], Fri Sep 06 00:00:00 GMT+500 2019=[], Sat Sep 14 00:00:00 GMT+500 2019=[], Tue Sep 17 00:00:00 GMT+500 2019=[]}
但是,当我尝试做同样的事情但日期按降序排列(timePeriods 列表)时,整个地图就搞砸了:
ConsoleLogger.java:32 {}
ConsoleLogger.java:32 {Wed Sep 25 00:00:00 GMT+500 2019=[]}
ConsoleLogger.java:32 {Tue Sep 17 00:00:00 GMT+500 2019=[], Wed Sep 25 00:00:00 GMT+500 2019=[]}
ConsoleLogger.java:32 {Sat Sep 14 00:00:00 GMT+500 2019=[], Tue Sep 17 00:00:00 GMT+500 2019=[], Wed Sep 25 00:00:00 GMT+500 2019=[]}
ConsoleLogger.java:32 {Fri Sep 06 00:00:00 GMT+500 2019=[], Sat Sep 14 00:00:00 GMT+500 2019=[], Tue Sep 17 00:00:00 GMT+500 2019=[], Wed Sep 25 00:00:00 GMT+500 2019=[]}
ConsoleLogger.java:32 {Wed Sep 04 00:00:00 GMT+500 2019=[], Fri Sep 06 00:00:00 GMT+500 2019=[], Sat Sep 14 00:00:00 GMT+500 2019=[], Tue Sep 17 00:00:00 GMT+500 2019=[], Wed Sep 25 00:00:00 GMT+500 2019=[]}
ConsoleLogger.java:32 {Mon Sep 02 00:00:00 GMT+500 2019=[1:00-2:00], Wed Sep 04 00:00:00 GMT+500 2019=[], Fri Sep 06 00:00:00 GMT+500 2019=[], Sat Sep 14 00:00:00 GMT+500 2019=[], Tue Sep 17 00:00:00 GMT+500 2019=[], Wed Sep 25 00:00:00 GMT+500 2019=[]}
每次放置某些东西时,它都会按升序对地图进行排序。 为什么会这样? 如何覆盖它?
另一个绕过它来创建当前地图的副本并调用Collections.reverse(),但由于性能问题我不想这样做。
提前致谢。
【问题讨论】:
-
你在问为什么 TreeMap 会根据它的 Keys 对自己进行排序吗?因为这实际上是 TreeMap 的全部意义所在。如果你想保持插入顺序,你只需要使用另一种类型的映射(如 LinkedHashMap)
-
"...但日期按降序排列..." - 请注意,您的 TreeMap 使用键的自然顺序,即日期升序。如果您希望地图按降序排序,您需要提供一个倒置的“自然顺序”比较器,例如通过
Comparator.naturalOrder().reversed(). -
只要实现
Comparable,TreeMap将自动对您的键进行排序,而不管插入顺序如何。如果您想始终按降序对它们进行排序并且不想覆盖它们的行为(使用Date)或元素实际上是最终的(例如Strings),则需要在初始化时注入ComparatorMap。您还可以在其上调用descendingMap以生成反向排序的地图,这似乎是这里最简单的解决方案。 -
是的,非常感谢,我知道了。初始化地图时我该怎么做?
-
@JoeD 使用正确的 TreeMap 构造函数。
标签: java collections treemap