尝试对具有时间戳和文本的列表进行反向排序

Trying to reverse sort a list which has timestamps along with the text

提问人:Mountain 提问时间:10/9/2023 最后编辑:AbraMountain 更新时间:10/30/2023 访问量:101

问:

我正在尝试使用反向排序代码对具有日期和时间戳值的列表进行反向排序:

List<String> sortValues = new ArrayList<>(List.of("2023-10-04 18:05:12","2023-10-04 18:06:22","2023-10-04 18:04:12","Unknown","2023-10-04 17:05:45","2023-10-04 18:04:45", "Error"));

@Bohemian提供的代码,非常感谢,我很感激你的帮助。

sortValues.sort(Comparator.<String, String>comparing(s -> !s.matches("\\d[\\d,]*") ? " " + s : String.format("%09d", Integer.parseInt(s.replace(",", "")))).reversed());

示例输入数组 1(即排序之前):

[Unknown, Unknown, 13, 125, 65, 029, 280, 552, 281, 012, 987, 072, 988, 775, 1, 250, 203, 2, 363, 356, 4, 042, 563]

示例输入数组 2:

["2023-10-04 18:05:12","2023-10-04 18:06:22","2023-10-04 18:04:12","Unknown","2023-10-04 17:05:45","2023-10-04 18:04:45","2023-10-04 18:04:47","2023-10-04 18:03:15", "Error"]

使用上面的代码,当存在示例 1(数字)中的值时,排序将按预期工作(数字在前,文本值在末尾)。

但是,当我对日期和时间戳值进行反向排序时,如示例 2 所示,上面的代码首先对文本值进行排序和显示,并在文本之后显示日期和时间戳。下面是一个示例。

[Unknown, Error, 2023-10-04 18:06:22, 2023-10-04 18:05:12, 2023-10-04 18:04:47, 2023-10-04 18:04:45, 2023-10-04 18:04:12, 2023-10-04 18:03:15, 2023-10-04 17:05:45]

而预期的反向排序应该是时间/日期格式,然后是文本。

谢谢你,我很感激你的帮助。

爪哇岛 正则表达式 列表 排序

评论

0赞 VGR 10/9/2023
“(数字在前,文本值在末尾)”这不是您的第一个示例包含的内容。

答:

0赞 Reilas 10/10/2023 #1

您可以利用 DateTimeFormatter 类来计算每个条目。

下面是一个示例。

DateTimeFormatter f = DateTimeFormatter.ISO_DATE_TIME;
sortValues.sort((a, b) -> {
    try {
        LocalDateTime t = (LocalDateTime) f.parse(a);
        try {
            return t.compareTo((LocalDateTime) f.parse(b));
        } catch (DateTimeParseException e) {
            return 1;
        }
    } catch (DateTimeParseException e) {
        try {
            f.parse(b);
            return -1;
        } catch (DateTimeParseException ee) {
            return a.compareTo(b);
        }
    }
});

并且,要颠倒顺序,请再次调用进行排序

sortValues.sort(Comparator.reverseOrder());

输出

2023-10-04 17:05:45
2023-10-04 18:04:12
2023-10-04 18:04:45
2023-10-04 18:05:12
2023-10-04 18:06:22
Error
Unknown
Unknown
Error
2023-10-04 18:06:22
2023-10-04 18:05:12
2023-10-04 18:04:45
2023-10-04 18:04:12
2023-10-04 17:05:45
0赞 Joshua 10/30/2023 #2

我相信您的问题是您实际上并没有对比较器做任何事情,因为 matches 方法中的正则表达式总是返回 false(一旦它被否定,就会返回 true)。当你意识到这一点时,你的代码行就变成了

sortValues.sort(Comparator.<String, String>comparing( s->" "+s )); 

sortValues.sort(Comparator.naturalOrder());

注意:这是没有 .reverse() 方法的

要解决此问题,您需要添加一个 do 两个单独的排序(可能有一种方法可以用一个来做到这一点,但这是我能做的最好的)。第一种排序是设置所有时间的顺序,然后您要进行第二次比较以将所有单词移动到末尾。它应该看起来像这样:

sortValues.sort(Comparator.<String>naturalOrder());
sortValues.sort(Comparator.comparing(s->((String)s).matches("[A-Za-z]*")));

然后,要获得时间的反转,您只需在第一个排序上应用 .reverse() 方法:

sortValues.sort(Comparator.<String>naturalOrder().reverse());
sortValues.sort(Comparator.comparing(s->((String)s).matches("[A-Za-z]*")));

P.S. 匹配的正则表达式仍然不完美。对于包含字母以外的任何内容的任何字符串,它将返回 false。如果无效条目将比这更复杂,请使用 this 而不是第二行:

sortValues.sort(Comparator.comparing(s->((String)s).matches(s.matches( "[0-9]{4}[[-][0-9]{2}]{2}.*[[0-9]{2}[:]]{2}[0-9]{2}") && s.length()==19 && s.charAt(10)==' ' )));