Java 对名称和日期数组进行排序

Java 对名称和日期数组进行排序,java,Java,我有一个字符串文件夹名称数组,每个名称包括日期、时间和时区。阵列如下所示: [ "folder_name_01-18-2020-19_00_00_PM_EST", "folder_name_05-01-2019-00_00_00_AM_EDT", "folder_name_12-15-2019-02_00_00_AM_EST" ] 如何对该数组进行排序,以便所有文件夹名称按日期(从早到晚)升序排序,例如,上述数组的结果应为: [ "folder_name_05-

我有一个字符串文件夹名称数组,每个名称包括日期、时间和时区。阵列如下所示:

[
    "folder_name_01-18-2020-19_00_00_PM_EST",
    "folder_name_05-01-2019-00_00_00_AM_EDT",
    "folder_name_12-15-2019-02_00_00_AM_EST"
]
如何对该数组进行排序,以便所有文件夹名称按日期(从早到晚)升序排序,例如,上述数组的结果应为:

[
    "folder_name_05-01-2019-00_00_00_AM_EDT",
    "folder_name_12-15-2019-02_00_00_AM_EST",
    "folder_name_01-18-2020-19_00_00_PM_EST"
]
保证文件夹名称字符串的格式与此完全相同<代码>文件夹名称从不更改,因此每个文件夹名称只会更改时间戳

我想到了一个听起来效率很低的高级解决方案:

Isolate the datetime from the folder name
Map the datetime to full folder name: {"05-01-2019-00_00_00_AM_EDT":"folder_name_05-01-2019-00_00_00_AM_EDT"}
Add the isolated datetime to an array
Sort the array of datetimes // potential trouble spot b/c of the date format
result = new array()
For item in sorted array:
    result.add(map.get(item))
return result

我想知道是否可以使用改进和/或更好的方法来解决此问题

您的高级解决方案并不是特别低效。但是,还有一条更有效的路线:

Arrays.sort(theArray, Comparator.comparing(CALCFUNCTION));
其中,CALCFUNCTION位是计算将用于排序顺序的值的函数。你要找的是将
文件夹名称\u 01-18-2020-19\u 00\u PM\u EST
转换成
20201801190000
,这很容易用一个

例如:

private static final Pattern EXTRACTOR = Pattern.compile(
  "^.*_(\\d+)-(\\d+)-(\\d+)-(\\d+_\\d+_\\d+)_[AP]M_[A-Z]{1,4}$");

Arrays.sort(theArray, Comparator.comparing(elem -> {
    var m = EXTRACTOR.matcher(elem);
    if (!m.matches()) return "uhoh. That was unexpected.";
    return m.group(3) + m.group(2) + m.group(1) + m.group(4);
}));

使用自定义的
比较器
找到了一个更好的解决方案:使用
substring()
函数获取日期时间,使用
SimpleDateTime
解析它,从生成的
date
对象中获取历元时间,然后使用
Long.compare()
确定哪个时间更晚

到目前为止你试过什么?你被困在哪里?你能给我们一些代码吗?另一个原因,似乎我们还需要一个,要求日期格式总是以主要/次要格式显示,例如YYYY-MM-DD格式。特别是在美国格式(MM-DD-YYYY)中,从来都不是最糟糕的选择。@Pablo在原始帖子中添加了我自己的想法。在这里,时区的加入很重要。您必须将这些片段解析为实际的日期/时间值以进行比较。您不能使用简单的字符串比较。这些文件名的格式很糟糕…了解ISO 8601标准,了解将日期时间值交换为文本时使用的格式。不要使用2-4个字母的伪时区,例如
EDT
&
EDT
,因为它们不是标准化的,甚至不是唯一的!实时时区名称的格式为
大陆/地区
,例如
美国/蒙特利尔
。更好的是,学会适应UTC。这个函数如何解释夏令时之类的变化?例如:
11-03-2019-01_00_00_AM_EDT
早于
11-03-2019-01_00_AM_EST
,但两者都将被表示为
201903110100000
@erli-您在这里的评论非常准确。再多的正则表达式匹配或字符串操作也解决不了这个问题;您必须将其转换为具有适当时区的日期/时间。我的第一种方法可能是查看Java的类。日期字符串的确切格式不常见,也没有指定。是的,首先转换为相关的java.time类型(幸运的是,这些类型通常也具有可比性),但是由于格式非常混乱,需要进行一些小步骤。