我希望根据

  1. 日期(yyMMdd)以字符串形式显示.
  2. 给定字符串的动态子字符串.(附件、dscl、xml)

这些是输入字符串.

f1660.msg.220523.xml.gpg
f1660.msg.dscl.220523.xml.gpg
f1660.msg.att.220523.tar.gz.gpg
f1660.cit.msg.220520.xml1.gpg
f1660.cit.msg.220520.xml2.gpg
f1660.cit.msg.att.220520.tar.gz.gpg
f1660.cit.msg.dscl.220520.xml.gpg
8701D6.msg.220524.xml.gpg
8701D6.dscl.220524.xml.gpg
8701D6.msg.att.220524.tar.gz.gpg

预期结果:根据日期(220520、220523、220524)排序,所有相同日期的文件应按其中的顺序排序.att文件优先.dscl文件第二个,其余全部.xml文件位于病房的第三位.

f1660.cit.msg.att.220520.tar.gz.gpg
f1660.cit.msg.dscl.220520.xml.gpg
f1660.cit.msg.220520.xml1.gpg
f1660.cit.msg.220520.xml2.gpg
f1660.msg.att.220523.tar.gz.gpg
f1660.msg.dscl.220523.xml.gpg
f1660.msg.220523.xml.gpg
8701D6.msg.att.220524.tar.gz.gpg
8701D6.dscl.220524.xml.gpg
8701D6.msg.220524.xml.gpg

try 提取日期并基于日期排序,但当日期和动态子字符串是我要排序的字符串的一部分时,我不知道如何实现它.

你能帮忙吗?

已try 代码.

public void sortBasedOnDate() {
    ArrayList<String> names = new ArrayList<>();
    names.add("f1660.msg.220523.xml.gpg");
    names.add("f1660.msg.dscl.220523.xml.gpg");
    names.add("f1660.msg.att.220523.tar.gz.gpg");
    names.add("f1660.cit.msg.220520.xml1.gpg");
    names.add("f1660.cit.msg.220520.xml2.gpg");
    names.add("f1660.cit.msg.att.220520.tar.gz.gpg");
    names.add("f1660.cit.msg.dscl.220520.xml.gpg");
    names.add("8701D6.msg.220524.xml.gpg");
    names.add("8701D6.dscl.220524.xml.gpg");
    names.add("8701D6.msg.att.220524.tar.gz.gpg");
    TreeMap<LocalDate, List<String>> map = new TreeMap<>(new SortByDate());
    for (String name : names) {
        LocalDate localDate = getDateFromFileName(name);
        List<String> mapList = map.get(localDate);
        if (mapList == null) {
            mapList = new ArrayList<>();
            mapList.add(name);
            map.put(localDate, mapList);
        } else {
            mapList.add(name);
        }
    }
    List<String> sortedList = new LinkedList<>();

    for (Map.Entry<LocalDate, List<String>> entry : map.entrySet()) {
        sortedList.addAll(entry.getValue());
    }
   
    System.out.println("sortedList: "+sortedList);
}

private LocalDate getDateFromFileName(String fileName) {
    String fileUtilDateStr = "";
    Optional<String> streamResult = Arrays.stream(fileName.split("\\."))
            .filter(element -> Pattern.compile("(\\d){6}").matcher(element).matches()).findFirst();
    if (streamResult.isPresent()) {
        fileUtilDateStr = streamResult.get();
    }
    DateTimeFormatter formatters = DateTimeFormatter.ofPattern("yyMMdd");
    LocalDate parsedDate = LocalDate.parse(fileUtilDateStr, formatters);
    return parsedDate;
}

public class SortByDate implements Comparator<LocalDate> {
@Override
public int compare(LocalDate date1, LocalDate date2) {
    return date1.compareTo(date2);
 }
}

输出:

  sortedList: [f1660.cit.msg.220520.xml1.gpg, 
    f1660.cit.msg.220520.xml2.gpg, f1660.cit.msg.att.220520.tar.gz.gpg, f1660.cit.msg.dscl.220520.xml.gpg, f1660.msg.220523.xml.gpg, f1660.msg.dscl.220523.xml.gpg, f1660.msg.att.220523.tar.gz.gpg, 8701D6.msg.220524.xml.gpg, 8701D6.dscl.220524.xml.gpg, 8701D6.msg.att.220524.tar.gz.gpg]

但预期列表:

  sortedList: [f1660.cit.msg.att.220520.tar.gz.gpg, 
   f1660.cit.msg.dscl.220520.xml.gpg, f1660.cit.msg.220520.xml1.gpg, f1660.cit.msg.220520.xml2.gpg, f1660.msg.att.220523.tar.gz.gpg, f1660.msg.dscl.220523.xml.gpg, f1660.msg.220523.xml.gpg, 8701D6.msg.att.220524.tar.gz.gpg, 8701D6.dscl.220524.xml.gpg, 8701D6.msg.220524.xml.gpg]

它是基于日期进行排序,但不知道如何使用第二个条件进行排序,即在同一日期内按照att、dscl和xml的顺序进行排序.

推荐答案

你可以

  • 使用正则表达式获取字符串的比较相关部分,即.
  • 使用函数、方法或UnaryOperator从中提取日期和扩展名
  • 为扩展创建优先级映射
  • 创建一个比较器,通过将日期部分解析为LocalDate来比较日期部分
  • 创建一个比较器,通过优先级映射的值来比较扩展
  • 最后,将比较器链接起来,根据需要对列表进行排序

示例:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Map;
import java.util.function.UnaryOperator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Example {

    public static void main(String[] args) {
        ArrayList<String> names = new ArrayList<>();
        names.add("f1660.msg.220523.xml.gpg");
        names.add("f1660.msg.dscl.220523.xml.gpg");
        names.add("f1660.msg.att.220523.tar.gz.gpg");
        names.add("f1660.cit.msg.220520.xml1.gpg");
        names.add("f1660.cit.msg.220520.xml2.gpg");
        names.add("f1660.cit.msg.att.220520.tar.gz.gpg");
        names.add("f1660.cit.msg.dscl.220520.xml.gpg");
        names.add("8701D6.msg.220524.xml.gpg");
        names.add("8701D6.dscl.220524.xml.gpg");
        names.add("8701D6.msg.att.220524.tar.gz.gpg");

        Pattern pattern = Pattern.compile("\\.(\\w+)\\.(\\d+)\\.");

        UnaryOperator<String> extnExtractor = s -> {
            Matcher m = pattern.matcher(s);
            m.find();
            return m.group(1);
        };

        UnaryOperator<String> dateExtractor = s -> {
            Matcher m = pattern.matcher(s);
            m.find();
            return m.group(2);
        };

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyMMdd");

        Map<String,Integer> prio = new HashMap<>();
        prio.put("att", 1);
        prio.put("dscl", 2);

        Comparator<String> byDate =  Comparator.comparing(s -> LocalDate.parse(dateExtractor.apply(s), dtf));
        Comparator<String> byExt  =  Comparator.comparing(s -> prio.getOrDefault(extnExtractor.apply(s),3));

        names.sort(byDate.thenComparing(byExt));

        names.forEach(System.out::println);
    }
}

Java相关问答推荐

如何用Java表示C++类以通过FFI使用?

Informix PrepareStatement引发错误-将LIMIT Clause添加到查询时,字符到数字的转换过程失败

try Dockerize Maven应用程序,但发布版本21不支持"

那么比较似乎不是词典学的,尽管doctor 这么说

try 使用Java 9或更高版本对特殊对象图进行解析时出现NullPointerException

在AnyLogic中增加变量计数

Spring Boot 3.2.2中的@Inject和@Resource Remove

获取字符串中带空格的数字和Java中的字符

使用Spring和ActiveMQ的侦听器方法引发属性名称不能重复为空警告

PDFBox未加载内容

在执行流和相关操作时,使用Java泛型为2个方法执行相同的操作,但对象不同

Kotlin Val是否提供了与Java最终版相同的可见性保证?

如何配置空手道以使用FeignClient或RestTemplate代替ApacheHttpClient

Java中HashSet的搜索时间与TreeSet的搜索时间

除0错误/抱歉我的句子是PT

每次我需要时创建和关闭数据库连接会有什么效果吗?

JavaFX标签中的奇怪字符

将BlockingQueue+守护程序线程替换为执行器

OpenJDK20:JEP434:Foreign Function&;内存API(第二次预览)

如何显示新布局