Java--高效输入
Posted 一只小余
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java--高效输入相关的知识,希望对你有一定的参考价值。
Java-高效输入
在一些输入数据量非常大的情况下,高效输入显得格外重要。
和高效输出一样适用于数据量特别大的io
不过呢和高效输出不一样的是,高效输入我觉得没有那么好用
没有Scanner好用,封装的方法少,需要自己手动来转换。
本文只介绍适用,不介绍具体的类。
方法:
- BufferedReader
- StreamTokenizer
BufferedReader
介绍
缓冲流来实现,因为我们一般读取的字符,所以使用字符流。
适用于字符串,如果需要其他类型,则可以通过切割、转换来实现。
适用
有规律的输入,便于切分。
构造
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
方法
-
br.read()
读取单个字符。 -
br.readLine()
读取一行文本。一行被视为由换行符 ('\\n')、回车符 ('\\r')、紧跟换行符的回车符或到达文件末尾 (EOF) 中的任何一个终止。 返回值: 包含行内容的字符串,不包括任何行终止字符,如果到达流的末尾而未读取任何字符,则为 null
StreamTokenizer
介绍
获取输入流并将其解析为“令牌”,允许一次读取一个令牌。解析过程由一个表和许多可以设置为各种状态的标志控制。流标记器可以识别标识符、数字、带引号的字符串和各种注释样式。
适用
适用于数字字符,因为一次只读取一个不适用于字符串。
构造
StreamTokenizer re = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
StreamTokenizer re = new StreamTokenizer(new InputStreamReader(System.in));
方法
-
re.nextToken();
分析此分词器的输入流中的下一个标记。下一个令牌的类型将在字段中返回 ttype 。有关令牌的其他信息可能位于 nval 此标记器的字段或 sval 字段中。
-
re.nval
如果当前令牌是数字,则此字段包含该数字的值。 此类的典型客户端首先设置语法表,然后位于调用 nextToken 的循环中,以解析连续的令牌,直到返回TT_EOF。
-
re.sval
如果当前标记是单词标记,则此字段包含一个字符串,用于提供单词标记的字符。 当当前标记是带引号的字符串标记时,此字段包含字符串的正文。 当字段的值 ttype 为 TT_WORD.当字段的值为引号字符时, ttype 当前标记是带引号的字符串标记。 此字段的初始值为 null。
用这个手动封装类来实现更多功能
封装StreamTokenizer
该类实现了基本的字符串、int、long、double、char类型的读取
package com.yu.inputUtils;
import java.io.*;
/**
* 自定义封装StreamTokenizer来实现高效输入
* @author yu
*/
public class SReader
StreamTokenizer reader;
public SReader()
reader = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public SReader(Reader r)
reader = new StreamTokenizer(r);
private int nt() throws IOException
return reader.nextToken();
public String next() throws IOException
int i = nt();
String a = "";
switch (i)
case StreamTokenizer.TT_WORD ->
return reader.sval;
case StreamTokenizer.TT_NUMBER ->
int n = (int) reader.nval;
if (reader.nval == n)
a = String.valueOf(n);
else
a = String.valueOf(reader.nval);
;
return a;
/**
* 获取下一个int数字
* @return int
* @throws IOException
*/
public int nextInt() throws IOException
nt();
return (int) reader.nval;
/**
* 获取下一个long数字
* @return long
* @throws IOException
*/
public long nextLong() throws IOException
nt();
return (long) reader.nval;
/**
* 获取下一个字符串的第一个字符
* @return char
* @throws IOException
*/
public char nextChar() throws IOException
nt();
return reader.sval.charAt(0);
/**
* 获取下一个都变了数字
* @return double
* @throws IOException
*/
public double nextDouble() throws IOException
nt();
return reader.nval;
public String toString()
return reader.toString();
下面是一些扩展代码,在一些场景下比较方便。
import java.util.ArrayList;// 格外加的
/**
* 获取输入的一行元素
* @return String[]
* @throws IOException
*/
public String[] line() throws IOException
ArrayList<String> wordList = new ArrayList<>();
int i = 0;
reader.eolIsSignificant(true);
while ((i = nt()) != StreamTokenizer.TT_EOL)
switch (i)
case StreamTokenizer.TT_WORD -> wordList.add(reader.sval);
case StreamTokenizer.TT_NUMBER -> wordList.add(String.valueOf(reader.nval));
reader.eolIsSignificant(false);
String[] a = new String[0];
return wordList.toArray(a);
/**
* 获取输入的一行数字
* @return Long[]
* @throws IOException
*/
public Long[] lLine() throws IOException
ArrayList<Long> wordList = new ArrayList<>();
reader.eolIsSignificant(true);
while (nt() != StreamTokenizer.TT_EOL)
wordList.add((long) reader.nval);
reader.eolIsSignificant(false);
Long[] a = new Long[0];
return wordList.toArray(a);
/**
* 获取输入的一行数字
* @return Integer[]
* @throws IOException
*/
public Integer[] iLine() throws IOException
ArrayList<Integer> wordList = new ArrayList<>();
reader.eolIsSignificant(true);
while (nt() != StreamTokenizer.TT_EOL)
wordList.add((int) reader.nval);
reader.eolIsSignificant(false);
Integer[] a = new Integer[0];
return wordList.toArray(a);
/**
* 获取一行浮点数
* @return Double[]
* @throws IOException
*/
public Double[] dLine() throws IOException
ArrayList<Double> wordList = new ArrayList<>();
reader.eolIsSignificant(true);
while (nt() != StreamTokenizer.TT_EOL)
wordList.add(reader.nval);
reader.eolIsSignificant(false);
Double[] a = new Double[0];
return wordList.toArray(a);
/**
* 获取一行字符串
* @return String[]
* @throws IOException
*/
public String[] sLine() throws IOException
ArrayList<String> wordList = new ArrayList<>();
int i = 0;
reader.eolIsSignificant(true);
while ( nt()!= StreamTokenizer.TT_EOL)
wordList.add(reader.sval);
reader.eolIsSignificant(false);
String[] a = new String[0];
return wordList.toArray(a);
/**
* 获取所有的字符串和数字,返回字符串数组
* 注意不适用于控制台输入,因为控制台不能判断结束
* @return String[]
* @throws IOException
*/
public String[] words() throws IOException
ArrayList<String> wordList = new ArrayList<>();
int i = 0;
while ((i = nt()) != StreamTokenizer.TT_EOF)
switch (i)
case StreamTokenizer.TT_WORD -> wordList.add(reader.sval);
case StreamTokenizer.TT_NUMBER -> wordList.add(String.valueOf(reader.nval));
String[] a = new String[0];
wordList.toArray(a);
return a;
封装BufferedReader
需要借助分词器StringTokenizer。
package com.yu.inputUtils;
import java.io.*;
import java.util.StringTokenizer;
public class BReader
public BufferedReader br;
public StringTokenizer tokenizer;
public BReader()
this(new InputStreamReader(System.in));
public BReader(Reader i)
br = new BufferedReader(i);
tokenizer = new StringTokenizer("");
public String next() throws IOException
while (!tokenizer.hasMoreTokens())
tokenizer = new StringTokenizer(br.readLine());
return tokenizer.nextToken();
public int nextInt() throws IOException
return Integer.parseInt(next());
public double nextDouble() throws IOException
return Double.parseDouble(next());
public String line() throws IOException
if (tokenizer.hasMoreTokens())
StringBuilder sb = new StringBuilder();
while (tokenizer.hasMoreTokens())
sb.append(tokenizer.nextToken());
sb.append(' ');
return sb.toString();
else
return br.readLine();
以上是关于Java--高效输入的主要内容,如果未能解决你的问题,请参考以下文章