Java 如何按日期和时间对地图数据进行排序,并按日期和/或一天中的小时进行汇总?
假设我有一个整数数据映射,其中键是日期和时间,格式如下: 2015年5月15日下午5:46 例如,我有: 2015年5月15日下午5:46,25Java 如何按日期和时间对地图数据进行排序,并按日期和/或一天中的小时进行汇总?,java,Java,假设我有一个整数数据映射,其中键是日期和时间,格式如下: 2015年5月15日下午5:46 例如,我有: 2015年5月15日下午5:46,25 2015年5月15日下午5:50,25 2015年5月15日下午6:15,30 2015年5月15日晚上8:05,40 2015年5月15日晚上10:46,10 2015年5月15日上午5:10,5 有没有办法按小时对这些数据进行排序?所以我可以吃一些像: 下午5点55分 下午6点30分 晚上8点40分 晚上10点,10点 日期也是一样的吗?如果您使用
2015年5月15日下午5:50,25
2015年5月15日下午6:15,30
2015年5月15日晚上8:05,40
2015年5月15日晚上10:46,10
2015年5月15日上午5:10,5
有没有办法按小时对这些数据进行排序?所以我可以吃一些像: 下午5点55分
下午6点30分 晚上8点40分 晚上10点,10点
日期也是一样的吗?如果您使用的是
java.util.Map
的实现类,我认为最好的方法是:
entrySet()
方法获取映射项集李>
比较器
类,以按小时升序对日期时间条目进行排序。您可以单独编写一个以按日期排序比较器
初始化树集的构造函数创建树集(一个排序表集
的实现)TreeSet.addAll()
从步骤1中获得的集合中复制和排序条目
keySet
并仅对键进行排序。然后,当您想按顺序访问映射元素时,您可以遍历已排序的键集
,并从已有的映射中提取相应的数字。map originalMap=…//你提到的地图
Map<String, Integer> originalMap = ... // the map you mentioned
Map<String, Integer> aggregationMap = new HashMap<String, Integer>();
DateFormat sdf = new SimpleDateFormat("MMM dd, yyyy hh:mm a", Locale.US);
// change "ha" to "yyyyMMdd" if you wanna do aggregation by date
DateFormat sdf2 = new SimpleDateFormat("ha", Locale.US);
Iterator<String> it = originalMap.keySet().iterator();
while (it.hasNext()) {
String k = it.next();
int v = originalMap.get(k);
String key = sdf2.format(sdf.parse(k));
Integer value = aggregationMap.get(key);
if (value == null) {
aggregationMap.put(key, v);
} else {
aggregationMap.put(key, v + value);
}
}
// TODO dump aggregationMap to see the result
Map aggregationMap=新HashMap();
DateFormat sdf=新的SimpleDateFormat(“mm dd,yyyy hh:mm a”,Locale.US);
//如果要按日期进行聚合,请将“ha”更改为“yyyyMMdd”
DateFormat sdf2=新的SimpleDataFormat(“ha”,Locale.US);
迭代器it=originalMap.keySet().Iterator();
while(it.hasNext()){
字符串k=it.next();
int v=原始映射get(k);
String key=sdf2.format(sdf.parse(k));
整数值=aggregationMap.get(键);
如果(值==null){
aggregationMap.put(键,v);
}否则{
aggregationMap.put(键,v+值);
}
}
//TODO转储aggregationMap以查看结果
首先,我假设您的原始数据存储在一个名为rawData
的成员字段Map
中。使用Java 8,这里是所需聚合摘要和排序逻辑的核心:
<T extends Comparable<? super T> & Temporal> SortedMap<T, Integer> summarize(
DateTimeFormatter keyFormat,
Function<LocalDateTime, ? extends T> keyTransform)
{
SortedMap<T, Integer> summaryData = new TreeMap<>();
rawData.forEach((k, v) -> {
LocalDateTime rawDateTime = LocalDateTime.parse(k, keyFormat);
T summaryKey = keyTransform.apply(rawDateTime);
summaryData.merge(summaryKey, v, (x, y) -> x + y);
});
return summaryData;
}
对summary
方法的调用使用lambda表达式将LocalDateTime
映射为LocalTime
(删除日期),该方法始终忽略分钟值,只保留小时。然后,它将得到的排序集传递给一个我稍后将介绍的方法,以输出到控制台,但您的实际程序很可能需要做的不仅仅是打印到屏幕上
你的问题没有给出一个“按日期”的预期产出的例子,所以我假设你想要像“2015年5月15日”这样的离散日,而不是几个月或任何特殊的时间的总和——只是总结整个24小时周期。使用上述方法的不同版本,只需更改摘要键类型、摘要转换和输出格式,即可轻松完成此操作:
void printSummaryByDate(DateTimeFormatter rawKeyFormat)
{
SortedMap<LocalDate, Integer> summary =
summarize(
rawKeyFormat,
LocalDateTime::toLocalDate
);
DateTimeFormatter summaryKeyFormat =
DateTimeFormatter.ofPattern("MMMM dd, yyyy", Locale.US); // e.g. "May 15, 2015"
print(summary, summaryKeyFormat::format);
}
产出:
上午5点,下午5点
下午5点50分
下午6点30分
晚上8点40分
晚上10点,10点
2015年5月15日,135
将它们转换为
LocalDateTime
或LocalTime
并进行比较,可能使用列表a集合。排序
…注意这不仅是排序,也是聚合。提取小时(例如通过regexp)作为记录的键,将其更改为24小时格式(例如5PM=17),然后按键排序。如果您使用数据库,您可以使用Orderby asc或DSCW获取数据原始问题的排序方面是什么?
void printSummaryByDate(DateTimeFormatter rawKeyFormat)
{
SortedMap<LocalDate, Integer> summary =
summarize(
rawKeyFormat,
LocalDateTime::toLocalDate
);
DateTimeFormatter summaryKeyFormat =
DateTimeFormatter.ofPattern("MMMM dd, yyyy", Locale.US); // e.g. "May 15, 2015"
print(summary, summaryKeyFormat::format);
}
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.util.*;
import java.util.function.Function;
public class StackOverflow30494397
{
private final Map<String, Integer> rawData = new HashMap<>();
public static void main(String... args)
{
StackOverflow30494397 instance = new StackOverflow30494397();
instance.rawData.put("May 15, 2015 5:46 PM", 25);
instance.rawData.put("May 15, 2015 5:50 PM", 25);
instance.rawData.put("May 15, 2015 6:15 PM", 30);
instance.rawData.put("May 15, 2015 8:05 PM", 40);
instance.rawData.put("May 15, 2015 10:46 PM", 10);
instance.rawData.put("May 15, 2015 5:10 AM", 5);
DateTimeFormatter rawKeyFormat =
DateTimeFormatter.ofPattern("MMMM dd, yyyy h:mm a", Locale.US);
instance.printSummaryByHour(rawKeyFormat);
instance.printSummaryByDate(rawKeyFormat);
}
private <K> void print(Map<K, ?> map, Function<? super K, String> keyFormatter)
{
map.forEach((k, v) -> System.out.printf("%s, %d%n", keyFormatter.apply(k), v));
System.out.println();
}
// INSERT OTHER METHODS (DESCRIBED IN ANSWER) HERE
}