在特定日期时间格式上运行数组索引超出范围Java
我编写了一个代码来对文档进行排序。文档由日期时间数据组成。在对文档进行排序之前,我编写了一段代码,将日期时间从Unix历元时间转换为常规日期时间。如果我将其转换为yyyy-MM-dd格式,如2013-10-10,排序程序可以很好地工作。但是如果我把它转换成E-yyy-MM-dd格式,比如2015-09-02 Wed,我总是会得到一个“数组索引越界错误”,考虑到我为数组索引输入了正确的数字,这很奇怪。现在我想知道,如果我输入了日期名称,为什么会出现这个错误,而如果我将它转换为常规的日期时间格式(没有日期名称),一切都很好。我有办法解决这个问题吗 下面是我用来对数据排序的代码。我认为这是一个非常糟糕且效率不高的代码(考虑到我的数据非常大,实际上它是一个大数据),但我现在想不出更好的代码了,而且它在我的笔记本电脑上运行得很好(不到10秒)。但任何建议都是受欢迎的。提前谢谢在特定日期时间格式上运行数组索引超出范围Java,java,arrays,datetime,Java,Arrays,Datetime,我编写了一个代码来对文档进行排序。文档由日期时间数据组成。在对文档进行排序之前,我编写了一段代码,将日期时间从Unix历元时间转换为常规日期时间。如果我将其转换为yyyy-MM-dd格式,如2013-10-10,排序程序可以很好地工作。但是如果我把它转换成E-yyy-MM-dd格式,比如2015-09-02 Wed,我总是会得到一个“数组索引越界错误”,考虑到我为数组索引输入了正确的数字,这很奇怪。现在我想知道,如果我输入了日期名称,为什么会出现这个错误,而如果我将它转换为常规的日期时间格式(没
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)