【问题标题】:Sort date strings in map [duplicate]对地图中的日期字符串进行排序[重复]
【发布时间】:2016-02-15 18:38:46
【问题描述】:

您好,我想根据以下日期对地图对象进行排序是地图

    testMap.put("06/15/2015", 1);
    testMap.put("05/15/2015", 2);
    testMap.put("01/15/2016", 4);
    testMap.put("07/15/2015", 3);
    testMap.put("02/15/2016", 5);

我需要如下序列的输出:

2015 年 5 月 15 日 2015 年 6 月 15 日 2015 年 7 月 15 日 2016 年 1 月 15 日 2016 年 2 月 15 日

我需要像 2015 年排序月份那样的输出,然后按排序顺序开始 2016 年的月份

我尝试过使用树形图,但如果日期字符串是 Date 格式,它曾经可以工作,任何人都可以帮助按照上述顺序进行排序

【问题讨论】:

    标签: java sorting date comparator


    【解决方案1】:

    TreeMap 创建一个自定义比较器:

    class DateComparator implements Comparator<String>, Serializable {
    
        public int compare(String date1, String date2) {
            int date1Int = convertDateToInteger(date1);
            int date2Int = convertDateToInteger(date2);
    
            return date1Int - date2Int;
        }
    
        // converts date string with format MM/DD/YYYY to integer of value YYYYMMDD
        private int convertDateToInteger(String date) {
            String[] tokens = date.split("/");
    
            return Integer.parseInt(tokens[2] + tokens[0] + tokens[1]);
        }
    }
    
    TreeMap<String, Integer> treeMap = new TreeMap<>(new DateComparator());
    

    这有利于避免Date 对象,这可能会减慢put 操作。

    06/15/201505/15/2015 之类的日期字符串会按照其时间顺序转换为可比较的整数等效值(分别为 2015061520150515)。

    然后您可以像往常一样添加键/值对,键将根据比较器进行排序:

    treeMap.put("06/15/2015", 1);
    treeMap.put("05/15/2015", 2);
    treeMap.put("01/15/2016", 4);
    treeMap.put("07/15/2015", 3);
    treeMap.put("02/15/2016", 5);
    

    【讨论】:

    • 你确定这个日期比较正确吗?看来您只是将整数相加并组成一个整数并进行比较!
    • 是的,06/15/2015 变为 2015061505/15/2015 20150515 并且这些整数是可比的。
    • Hacky 但很有趣。我似乎无法打破它。给我一些时间……也许我不能……
    • 为此,您需要确保日期与比较器所期望的格式相匹配。
    • 很好!!但我遇到了一些问题。我在地图下方添加了treeMap.put("06/15/2015", 1); treeMap.put("05/15/2015", 2); treeMap.put("01/15/2016", 4); treeMap.put("07/15/2015", 3); treeMap.put("02/15/2016", 5) 但结果我只看到{06/15/2015=3, 01/15/2016=5} 在这里我认为如果日期相同会有问题,我的案例日期将相同:(
    【解决方案2】:

    您可以通过实现Comparator&lt;String&gt; 并在创建新实例时告诉TreeMap 来做到这一点...

    public class DateAsStringComparator implements Comparator<String>, Serializable {
       public int compareTo(String o1, String o2) {
         // Convert to Date and compare here.
       }      
    }
    

    然后……

    final TreeMap<String, Integer> testMap = new TreeMap<>(new DateAsStringComparator());
    

    (代码未经测试,但应该给你一个大纲)。如果您计划序列化 TreeMap,请务必让您的 Comparator 实现 Serializable

    【讨论】:

    • 如果我实现了比较器接口,我需要重写该接口中存在的所有方法,对吗?
    • 是的。这是一个简单的界面(两种方法)。您的 IDE 可能会为您编写 equals 方法。
    【解决方案3】:

    其实Todd的回答是正确的使用TreeMap,我只是添加了比较器的实现。 最好将日期比较委托给 java.util.Date 内置的“compareTo”方法

    public class MyDateComparator implements Comparable<String>
    {
    
        public int compareTo( String d1, String d2 )
        {
           if( d1.matches("\\d{2}\\/\\d{2}\\/\\d{4}") && d2.matches("\\d{2}\\/\\d{2}\\/\\d{4}") )
           { 
             //Valid date format
             String[] date_contents =  d1.split("/");
             java.util.Date date1 = new java.util.Date(date_contents[2], date_contents[0], date_contents[1] );
             date_contents =  d2.split("/");
             java.util.Date date2 = new java.util.Date(date_contents[2], date_contents[0], date_contents[1] );
             return date1.compareTo(date2);
           }
    
           return d1.compareTo(d2);
       }
    
    
    
    });
    
    Map<String, String> treeMap = new TreeMap<String, String>(new MyDateComparator());
    

    【讨论】:

    • 我不禁觉得这最终会创建 很多 个 Date 对象,这会减慢速度。
    • 我明白了,但是你必须编写 Date 所做的复杂的比较代码。
    猜你喜欢
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2016-04-04
    相关资源
    最近更新 更多