如何基于字符串内的日期时间段对List<String>进行排序?
按字符串中的日期时间段排序List
问题分析
你的需求是对包含文件路径的List<String>进行排序,排序依据是路径末尾的日期时间字符串(格式如2023-09-11-19-30-10-00445)。观察该格式可知,字符串的字典序与时间先后顺序完全一致,因此可以直接提取该子串后进行比较,无需额外转换为日期对象(若需更严谨的日期校验,也可转换为日期类)。
解决方案
方法1:自定义Comparator排序
通过提取每个路径中的目标日期子串,基于子串的字典序实现排序:
import java.util.ArrayList; import java.util.Comparator; import java.util.List; public class PathSorter { public static void main(String[] args) { List<String> pathList = new ArrayList<>(); // 初始化待排序列表 pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt"); pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt"); pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt"); pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt"); pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt"); pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt"); pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt"); // 按提取的日期子串排序 pathList.sort(Comparator.comparing(PathSorter::extractDateTimeString)); // 输出排序结果 pathList.forEach(System.out::println); } // 提取路径中的日期时间子串 private static String extractDateTimeString(String path) { // 去掉末尾的.txt后缀 String withoutExtension = path.substring(0, path.lastIndexOf(".txt")); // 提取最后一个'-'之后的日期时间字符串 return withoutExtension.substring(withoutExtension.lastIndexOf('-') + 1); } }
方法2:Stream API排序(简洁风格)
如果偏好函数式编程,可通过Stream实现排序:
import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class PathSorterStream { public static void main(String[] args) { List<String> pathList = new ArrayList<>(); // 初始化待排序列表(同方法1) pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0057c620ea6040849da9bceb977e7332-2023-09-11-19-30-10-00445.txt"); pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_00e1cd4e425243bda8e09ee2b7b2334f-2023-09-11-19-30-02-00554.txt"); pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_021b63466ff6406d8b30b25bda63b49f-2023-09-11-19-30-21-00218.txt"); pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_049a681a00214155b7dab7c94c871341-2023-09-11-19-30-15-00036.txt"); pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_068e490f3b78453293e84bdfb49112ad-2023-09-11-19-30-14-00288.txt"); pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0694fca541d0486689c6591b16cb1fbc-2023-09-11-19-30-14-00405.txt"); pathList.add("datareplay/upstream/20230911/2023-09-11/WIRE_ISSN.WIRE_CRTD_0a8d4975741e4b088ead2bfd1edee1ad-2023-09-11-19-30-07-00188.txt"); // 排序并收集结果 List<String> sortedList = pathList.stream() .sorted(Comparator.comparing(path -> { String withoutExt = path.substring(0, path.lastIndexOf(".txt")); return withoutExt.substring(withoutExt.lastIndexOf('-') + 1); })) .collect(Collectors.toList()); // 输出结果 sortedList.forEach(System.out::println); } }
补充说明
- 若需要降序排序,只需在
Comparator.comparing()后添加.reversed()即可。 - 如果要确保日期格式合法,可将提取的子串转换为
LocalDateTime处理毫秒部分,示例如下:
排序时使用private static LocalDateTime parseDateTime(String dateStr) { String[] parts = dateStr.split("-"); String dateTimePart = String.join("-", Arrays.copyOfRange(parts, 0, 6)); int nano = Integer.parseInt(parts[6]) * 1000000; // 五位毫秒转纳秒 return LocalDateTime.parse(dateTimePart, DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss")) .plusNanos(nano); }Comparator.comparing(PathSorter::parseDateTime)即可。
内容的提问来源于stack exchange,提问作者NoobCoder
相关产品推荐
相关产品推荐

