根据日期对 List<String> 进行排序

Sort List<String> based on date

提问人:NoobCoder 提问时间:10/26/2023 最后编辑:John KugelmanNoobCoder 更新时间:10/30/2023 访问量:123

问:

我正在尝试根据其日期对它进行排序。列表:List<String>

[
    datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt,
    datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt,
    datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt,
    datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt,
    datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt,
    datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt,
    datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt
]

我想排序的部分是:

2023-09-11-19-30-10-00445
Java 列表 排序

评论


答:

1赞 Abra 10/26/2023 #1
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    private static final String REGEX = "-(\\d{4}-\\d{2}-\\d{2}-\\d{2}-\\d{2}-\\d{2}-\\d{5})\\.txt$";
    private static final Pattern PATTERN = Pattern.compile(REGEX);
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss-SSSSS", Locale.ENGLISH);

    private static int compare(String s1, String s2) {
        Matcher m1 = PATTERN.matcher(s1);
        m1.find();
        LocalDateTime ts1 = LocalDateTime.parse(m1.group(1), FORMATTER);
        Matcher m2 = PATTERN.matcher(s2);
        m2.find();
        LocalDateTime ts2 = LocalDateTime.parse(m2.group(1), FORMATTER);
        return ts1.isAfter(ts2) ? 1 : ts1.isBefore(ts2) ? -1 : 0;
    }

    public static void main(String[] args) {
        Comparator<String> c = Main::compare;
        List<String> tmp = List.of("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt",
                                   "datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt",
                                   "datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt",
                                   "datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt",
                                   "datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt",
                                   "datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt",
                                   "datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt");
        List<String> list = new ArrayList<>(tmp);
        Collections.sort(list, c);
        list.forEach(System.out::println);
    }
}

上面的代码实现了一个比较器来对列表进行排序。
使用正则表达式提取列表中每个字符串的相关部分。
然后,它将提取的字符串转换为 LocalDateTime,以确定时间顺序。
Comparator

请注意,方法中的第一行,即main

Comparator<String> c = Main::compare;

方法引用

这是我运行上述代码时的输出:

datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt

评论

0赞 NoobCoder 11/17/2023
你好,谢谢你的回复。你能解释一下的逻辑吗?@Abrareturn ts1.isAfter(ts2) ? 1 : ts1.isBefore(ts2) ? -1 : 0;
0赞 Abra 11/17/2023
你@NoobCoder阅读了我在回答中链接到的接口的文档吗?Comparator
0赞 Basil Bourque 10/26/2023 #2

TL的;博士

一句话:

"[datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt]"
        .replace ( "[" , "" )
        .replace ( "]" , "" )
        .replace ( ", " , "\n" )
        .lines ( )
        .sorted (
                Comparator.comparing ( ( String s ) -> s.substring (
                        "datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-".length ( ) ,
                        "datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445".length ( )
                ) )
        )
        .forEach ( System.out :: println );
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt

按摩输入。拆下括号。将每个 COMMA+SPACE 分隔符替换为 LINEFEED 字符。

String input = "[datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt]";
String modified =
        input
                .replace ( "[" , "" )
                .replace ( "]" , "" )
                .replace ( ", " , "\n" );

将修改后的字符串解析为行,在每个 LINEFEED 上断开。

List < String > lines =
        modified
                .lines ( )
                .toList ( );

这将导致一个不可修改的列表。为了排序,我们需要制作一个可修改的列表。

lines = new ArrayList <> ( lines ); // Make unmodifiable list modifiable.

通过指定比较器对行集合进行排序。我们的比较器将您的日期时间文本作为子字符串提取。所有行的长度都相同,因此我们可以很容易地确定要提取的字符位置的起始和结束索引进行排序。

无需解析为日期时间;按字母顺序排列的文本也按时间顺序排列。

int indexStart = "datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-".length ( );
int indexEnd = indexStart + "2023-09-11-19-30-10-00445".length ( );
Comparator < String > comparator = Comparator.comparing ( ( String s ) -> s.substring ( indexStart , indexEnd ) );

将比较器传递给 List#sort 方法。

lines.sort ( comparator );

做。

以下是完整的示例代码,包括一些将数据转储到控制台的代码。

public class SortingEmbedded
{
    public static void main ( String[] args )
    {
        String input = "[datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt]";
        String modified =
                input
                        .replace ( "[" , "" )
                        .replace ( "]" , "" )
                        .replace ( ", " , "\n" );
        List < String > lines =
                modified
                        .lines ( )
                        .toList ( );
        lines = new ArrayList <> ( lines ); // Make unmodifiable list modifiable.

        // Report before sorting.
        System.out.println ( "------------\nlines BEFORE sort = " );
        lines.forEach ( System.out :: println );
        System.out.println ( "------------" );

        // Sort
        int indexStart = "datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-".length ( );
        int indexEnd = indexStart + "2023-09-11-19-30-10-00445".length ( );
        Comparator < String > comparator = Comparator.comparing ( ( String s ) -> s.substring ( indexStart , indexEnd ) );
        lines.sort ( comparator );

        // Report after sorting.
        System.out.println ( "------------\nlines AFTER sort = " );
        lines.forEach ( System.out :: println );
        System.out.println ( "------------" );


        // Dump data.
        for ( String line : lines )
        {
            System.out.println ( line.substring ( indexStart , indexEnd ) );
        }
        System.out.println ( "------------\ninput = \n" + input );
        System.out.println ( "------------\nmodified = \n" + modified );
        System.out.println ( "------------\n" );
    }
}

运行时:

------------
lines BEFORE sort = 
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt
------------
------------
lines AFTER sort = 
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt
------------
2023-09-11-19-30-02-00554
2023-09-11-19-30-07-00188
2023-09-11-19-30-10-00445
2023-09-11-19-30-14-00288
2023-09-11-19-30-14-00405
2023-09-11-19-30-15-00036
2023-09-11-19-30-21-00218
------------
input = 
[datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt, datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt]
------------
modified = 
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt
datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt
------------
0赞 Joshua 10/30/2023 #3
  1. 将要排序依据的日期中的字母数字字符复制到每个字符串的前面
  2. 使用用于对字符串进行排序的默认方法对它们进行排序
  3. 然后删除您刚刚添加的字符

注意:使用 Stream 类很有帮助

你说你正在使用一个列表,但如果你指的是一个数组,我将包含两者的代码

如果您使用 List list 存储数据:

    list=list.stream().map(i->(i.substring(93,118).replaceAll("-", "")+i)).sorted().map(i->i.substring(19)).toList();

如果您使用 String[] 数组存储数据:

array=(String[])Arrays.stream(array).map(i->(i.substring(93,118).replaceAll("-", "")+i)).sorted().map(i->i.substring(19)).toArray(String[]::new);