按日期对文件的ArrayList进行排序

时间:2019-03-27 09:43:01

标签: android

我正在尝试按自定义格式按日期对文件列表进行排序,该格式显示在文件名本身中。 我不确定为什么,但这不能按预期工作。

这是我获取文件的方式:

a[i]

排序类:

    ArrayList<File> inFiles = new ArrayList<>();
    File[] sortedByDate = parentDir.listFiles();

    for (File file : sortedByDate) {
        if(file.getName().endsWith(".txt")){
            inFiles.add(file);
        }
    }
}
Collections.sort(inFiles, new FileNameCompare());

由于某种原因,这不起作用,并返回未排序的列表。 我在做什么错了?

已编辑: 在排序前后添加日志。

之前:

public class FileNameCompare implements Comparator<File> {

    @Override
    public int compare(File o1, File o2) {

        String name1 = o1.getName();
        String name2 = o2.getName();

        String substr1 = name1.substring(name1.length()-24, name1.lastIndexOf('.'));
        String substr2 = name2.substring(name2.length()-24, name2.lastIndexOf('.'));

        //This is a file name format for example:
        //XXXXX_XXXX_24_Mar_2019_13_02_25.txt

        Date d1 = null, d2 = null;
        SimpleDateFormat sdf = new SimpleDateFormat( "dd_MMM_yyyy_hh_mm_ss" , Locale.ENGLISH);

        try {
            d1 = sdf.parse(substr1);
            d2 = sdf.parse(substr2);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return (int)(d1.getTime() - d2.getTime());
    }
}

之后:

25_Mar_2019_01_03_53.txt"
25_Mar_2019_01_21_44.txt"
25_Mar_2019_04_59_02.txt"
25_Mar_2019_05_57_06.txt"
25_Mar_2019_06_37_35.txt"
25_Mar_2019_07_10_07.txt"
18_Jan_2019_10_31_25.txt"
18_Jan_2019_10_25_25.txt"
24_Jan_2019_13_02_25.txt"
19_Feb_2019_13_02_25.txt"
18_Mar_2019_10_31_25.txt"
18_Mar_2019_10_25_25.txt"
24_Mar_2019_13_02_25.txt"
09_Jan_2019_09_36_25.txt"
09_Jan_2019_09_02_25.txt"

3 个答案:

答案 0 :(得分:1)

int result = 0;
if(d1.getTime() - d2.getTime() > 0){
   result = 1;
} else if (d1.getTime() - d2.getTime() < 0) {
   result = -1;
}
return result;

将long强制转换为int可能是错误的

答案 1 :(得分:1)

Java 8或更高版本以及java.time

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd_MMM_uuuu_HH_mm_ss");

    Collections.sort(inFiles, Comparator.comparing(f -> {
        String name = f.getName();
        String substr = name.substring(name.length() - 24, name.lastIndexOf('.'));
        return LocalDateTime.parse(substr, formatter);
    }));

这不仅简短,而且首先更难弄错。

更早的Android,java.time和ThreeTenABP

class FileNameCompare implements Comparator<File> {

    static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd_MMM_uuuu_HH_mm_ss");

    @Override
    public int compare(File o1, File o2) {

        String name1 = o1.getName();
        String name2 = o2.getName();

        String substr1 = name1.substring(name1.length()-24, name1.lastIndexOf('.'));
        String substr2 = name2.substring(name2.length()-24, name2.lastIndexOf('.'));

        LocalDateTime ldt1 = LocalDateTime.parse(substr1, formatter);
        LocalDateTime ldt2 = LocalDateTime.parse(substr2, formatter);

        return ldt1.compareTo(ldt2);
    }
}

您的代码出了什么问题?

  1. int溢出
  2. 错误的日期时间格式模式字符串

我认为已经有人说过:您的int溢出了。每月只有两个日期,以毫秒为单位的差异就大于int中可以保持的差异(确切地说,限制为24天20小时31分钟23.647秒)。因此,在这一行中,您有时会返回错误的值:

        return (int)(d1.getTime() - d2.getTime());

要比较您可能刚使用过的Date对象:

        return d1.compareTo(d2);

比较long值的正确方法是:

        return Long.compare(d1.getTime(), d2.getTime());

进一步的提示:当您确实需要将long转换为int并提供long值不会使int溢出时,请养成习惯使用Math.toIntExact。在这种情况下,应该是

        return Math.toIntExact(d1.getTime() - d2.getTime());

它会捕获任何上溢或下溢并通过异常进行报告,因此这将告诉您问题所在。

程序中还有一个错误:格式模式字符串中的小写hh使用小时。 hh在01到12的AM或PM内持续一个小时,仅与AM / PM标记一起使用。对于一天中从00到23的小时,您需要使用大写字母HH。我敢打赌,在您的代码中,如果您有一个带有12小时标记的文件,则该文件将按照小时为00的顺序进行排序。

问题:我可以在Android上使用java.time吗?

是的,java.time在较新和较旧的Android设备上均可正常运行。它只需要至少 Java 6

  • 在Java 8和更高版本以及更新的Android设备(API级别26以上)中,内置了现代API。
  • 在Java 6和7中,获得了ThreeTen反向端口,这是现代类的反向端口(JSR 310的ThreeTen;请参见底部的链接)。
  • 在(较旧的)Android上,使用Android版本的ThreeTen Backport。叫做ThreeTenABP。并确保您使用子包从org.threeten.bp导入日期和时间类。

链接

答案 2 :(得分:0)

您可以使用lastModified这样对文件进行排序

    ArrayList<File> inFiles = new ArrayList<>();
    Collections.sort(inFiles , new Comparator<File>() {

    @Override
    public int compare(File file1, File file2) {
        long k = file1.lastModified() - file2.lastModified();
        if(k > 0){
           return 1;
        }else if(k == 0){
           return 0;
        }else{
          return -1;
       }
    }
});

请注意,如果您更改文件名或代码中的任何属性,则此逻辑将不起作用,您将需要更改文件排序方式的逻辑。