Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何按日期和时间对地图数据进行排序,并按日期和/或一天中的小时进行汇总?_Java - Fatal编程技术网

Java 如何按日期和时间对地图数据进行排序,并按日期和/或一天中的小时进行汇总?

Java 如何按日期和时间对地图数据进行排序,并按日期和/或一天中的小时进行汇总?,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: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点


日期也是一样的吗?

如果您使用的是
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    
    }