java io模板_快速的Java ACM IO模板

背景

对于大多数ACMer来说,Java I/O慢一直是个让人头疼的问题。由于Java的Scanner的实现太过复杂(为了满足更多高级特性),使用它输入会比C/C++的scanf慢好几倍,并且内存开销相当大。

目前网上最常见的快速模板是使用BufferedReader,带缓冲并且按行读入测试数据,然后使用StringTokenizer将每一行分片。但我找到的几个模板太过简单,虽然代码量少,却无法支持一些常用操作,比如:丢弃当前行,检索是否读取到了流尾,有一定局限性。 也有部分实现了这两个功能的模板,但一直没看到特别满意的,于是自己写了一个。题外话: 还有很多对Java一知半解的人给出new Scanner(new BufferedInputStream())这种”减速”方法,Scanner的实现中有缓冲,慢并不是慢在这里。

简介

Reader内部使用BufferedReader的nextLine方法从输入流读取数据,由内部方法innerNextLine包装,同样使用StringTokenizer分片。hasNext方法会检查是否还有数据,它通过读入新数据并创建tokenizer来寻找下一个可用的token。因此,调用hasNext方法后,会确保调用tokenizer.nextToken()时可以得到数据,除非已经读取到输入流尾。nextLine方法会读入一行新数据,同时舍弃tokenizer中的内容。next方法会返回下一个数据。nextXXX方法将next的数据包装成常见数据类型。

Writer则是对BufferedWriter的简单包装,提供了接受Object的print和println方法。注意,程序结束前一定要调用Writer的close方法来刷新缓冲区并关闭输出流

性能测试

测试题目:给出未知行,每行第一个数N,随后给出N个数,求N个数之和。

测试输入:1000w行,均为5 1 10 100 1000 10000,结果为11111

测试环境:Windows10 i7-7700HQ

Java: OpenJDK 12

C++: MinGW GCC方法执行时间峰值内存平均内存

Scanner91.2s88.7MB81.5MB

Scanner(缓冲输入流包装 错误用法)106.9s96.2MB81.5MB

Java快速IO模板9.8s84.1MB79.1MB

cin / cout107.5s0.4MB0.4MB

scanf / printf10.1s0.4MB0.4MB

C / C++输入输出挂2.4s0.4MB0.4MB

模板class AReader {

private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

private StringTokenizer tokenizer = new StringTokenizer("");

private String innerNextLine() {

try {

return reader.readLine();

} catch (IOException ex) {

return null;

}

}

public boolean hasNext() {

while (!tokenizer.hasMoreTokens()) {

String nextLine = innerNextLine();

if (nextLine == null) {

return false;

}

tokenizer = new StringTokenizer(nextLine);

}

return true;

}

public String nextLine() {

tokenizer = new StringTokenizer("");

return innerNextLine();

}

public String next() {

hasNext();

return tokenizer.nextToken();

}

public int nextInt() {

return Integer.parseInt(next());

}

}

class AWriter implements Closeable {

private BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

public void print(Object object) throws IOException {

writer.write(object.toString());

}

public void println(Object object) throws IOException {

writer.write(object.toString());

writer.write("\n");

}

@Override

public void close() throws IOException {

writer.close();

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值