在特定日期时间格式上运行数组索引超出范围Java

在特定日期时间格式上运行数组索引超出范围Java,java,arrays,datetime,Java,Arrays,Datetime,我编写了一个代码来对文档进行排序。文档由日期时间数据组成。在对文档进行排序之前,我编写了一段代码,将日期时间从Unix历元时间转换为常规日期时间。如果我将其转换为yyyy-MM-dd格式,如2013-10-10,排序程序可以很好地工作。但是如果我把它转换成E-yyy-MM-dd格式,比如2015-09-02 Wed,我总是会得到一个“数组索引越界错误”,考虑到我为数组索引输入了正确的数字,这很奇怪。现在我想知道,如果我输入了日期名称,为什么会出现这个错误,而如果我将它转换为常规的日期时间格式(没

我编写了一个代码来对文档进行排序。文档由日期时间数据组成。在对文档进行排序之前,我编写了一段代码,将日期时间从Unix历元时间转换为常规日期时间。如果我将其转换为yyyy-MM-dd格式,如2013-10-10,排序程序可以很好地工作。但是如果我把它转换成E-yyy-MM-dd格式,比如2015-09-02 Wed,我总是会得到一个“数组索引越界错误”,考虑到我为数组索引输入了正确的数字,这很奇怪。现在我想知道,如果我输入了日期名称,为什么会出现这个错误,而如果我将它转换为常规的日期时间格式(没有日期名称),一切都很好。我有办法解决这个问题吗

下面是我用来对数据排序的代码。我认为这是一个非常糟糕且效率不高的代码(考虑到我的数据非常大,实际上它是一个大数据),但我现在想不出更好的代码了,而且它在我的笔记本电脑上运行得很好(不到10秒)。但任何建议都是受欢迎的。提前谢谢

public static void main(String[] args) {
    try {Scanner scanner = new Scanner(new File("file.txt"));

        int number = 1710680;
        String dataList[] = new String[number];
        int count = 0;

        while (scanner.hasNext()) {
            dataList[count] = String.valueOf(scanner.next());
            count++;
        }

        Arrays.sort(dataList);


        try (FileWriter file = new FileWriter("file.txt)) {
            String newLine = System.getProperty("line.separator");

            //read the header first, so it won't be processed in the looping
            for(String data : dataList){
                file.write(data+newLine);
            }
            System.out.println("Done now");
            System.out.println("Check your file");
        }catch(Exception e){
            System.out.println("Failed here -> "+e.getMessage());

            System.err.println(e);
        }


    } catch (Exception e) {
        System.out.println("Failed -> " + e.getMessage());

        System.err.println(e);
    }

}

我想我刚刚意识到了一个显而易见的问题:问题在于文件格式的定义和文件的解析器之间

如果我理解正确,您有一个单独的程序(未显示),它接受数字(Unix时间戳),将时间戳格式化为文本,并将它们写入文件“file.txt”。然后,您会看到一个程序,它试图对文件中的文本进行排序

您将使用将文件解析为单独的标记,然后对这些标记进行排序。仔细阅读文档以确定其是否适合您的数据:

扫描器使用定界符模式将其输入拆分为标记,默认情况下,定界符模式匹配空白

当文件内容看起来像:

2015-01-01 2015-10-02 2015-02-05
2014-12-21 2013-03-08
然后您将从
扫描仪中获得5个令牌

但是,当文件内容看起来像

2015-01-01 Wed 2015-10-02 Mon 2015-02-05 Thu
2014-12-21 Sun 2013-03-08 Sat
然后您将从
扫描仪
中获得10个代币。这就是为什么会出现
ArrayIndexOutOfBounds
异常:您拥有的令牌数量是在数组中分配的空间的两倍

如果文件内容如下所示:

2015-01-01 Wed
2015-10-02 Mon
2015-02-05 Thu
2014-12-21 Sun
2013-03-08 Sat
然后使用
BufferedReader
读取数据,或者只使用现有程序


更好的是,在将时间戳格式化为文本的程序中,只需首先对时间戳进行排序。

考虑使用java 8流和字符串到日期的转换:

public static void main(String[] args) throws IOException {
    DateFormat inFormat = new SimpleDateFormat("yyyy-M-dd", Locale.ENGLISH);
    DateFormat outFormat  = new SimpleDateFormat("EEE MMM dd kk:mm:ss z yyyy", Locale.ENGLISH);
    Path input = Paths.get("file.txt");
    Path output = Paths.get("outfile.txt");
    List<String> dataList = Files
        .readAllLines(input) //list of strings
        .stream() //java 8 stream
        .map(string -> {
            try {
                return inFormat.parse(string);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return null;
        }) //strings converted to dates
        .filter(date -> date != null) //filtered non null dates
        .sorted()
        .map(outFormat::format) //dates converted to strings
        .collect(Collectors.toList()); //Stream<String> collected to List<String>


    if( dataList.size() > 0) {
        //write all lines
        Files.write(output, dataList, Charset.defaultCharset(), StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
    }

    System.out.println("Done now");
    System.out.println("Check your file");

}

使用具有动态大小的列表而不是数组

如果您只是对时间进行排序,请使用
列表而不是
字符串
列表,然后将其项转换为
日期
。比较long要比比较字符串快得多。分配1710680数组是相当,嗯,不寻常的-我认为你的文件上没有那么多的日期。--在这段代码中,这个越界异常发生在哪里?但是我的数据中有一个日期名称,我想我不能用long。这就是为什么我用字符串来代替。是的,有那么多数据。正如我前面所说,这是一个大数据。停止捕捉异常。发布你得到的异常的完整堆栈跟踪。也许当你在每个日期添加一个额外的令牌时,你的数组就不够大了?究竟为什么要使用数组而不是ArrayList?当您试图以危险的方式读取基于文件的输入时,硬编码数据的大小。
public static void main(String[] args) throws IOException {
    DateFormat inFormat = new SimpleDateFormat("yyyy-M-dd", Locale.ENGLISH);
    DateFormat outFormat  = new SimpleDateFormat("EEE MMM dd kk:mm:ss z yyyy", Locale.ENGLISH);

    Path input = Paths.get("file.txt");

    List<Date> dateList = new ArrayList<>();

    for( String string: Files.readAllLines(input)) {
        try {
            dateList.add(inFormat.parse(string));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
    dateList.sort(Date::compareTo);
    FileWriter outfile = new FileWriter("file.txt");
    for(Date date: dateList) {
        outfile.write(outFormat.format(date));
    }

    System.out.println("Done now");
    System.out.println("Check your file");

}
Files.readAllLines(input)