1.输入输出
提到了几个IO类,这里推荐使用BufferedReader输入,BufferedWriter输出,当输入输出的数据量大于一百万左右就必须使用快速IO不能直接使用Scanne和System.out.print。
1.1 正常输入输出
输入
首先定义一个Scanner对象,需要导入包:import java.util.Scanner;
单个输入
import java.util.Scanner;
/**
* @author wld
* @date 2022/1/19 - 15:31
*/
public class LQ1_InputOutput {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int i = in.nextInt();
double d = in.nextDouble();
String s1 = in.next(); //String类型,遇到空格结束
String s2 = in.nextLine(); //String类型,读取一行数据,遇到换行结束,类似gets
}
}
多组输入:使用in.hasNext,返回值是bool值,作用是当在缓冲区内扫描到字符时,会返回true, 否则会发生阻塞,等待数据输入,所以in.hasNext()是不会返回false的。使用 while + in.hasNext() 相当于 while(scanf())。和in.nextXXX()方法类似,in.hasNextXXX()也有针对不同类型变量的方法。
class LQ2_InputOutput{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
double a, b;
int c;
while (in.hasNext()){
a = in.nextDouble();
b = in.nextDouble();
c = in.nextInt();
System.out.println(a + b + c);
}
in.close();
}
}
输出
System.out.printf(); //和C/C++中的printf一样。 可使用格式控制符进行格式化输出。
System.out.printf("%d",a); // 例如: 输出一个int类型变量
System.out.print(); //不能使用格式控制符进行格式化输出,仅输出变量
System.out.println(); //不能使用格式控制符进行格式化输出,仅输出变量,但会自动输出一个换行。
1.2 快速输入输出
1.2.1 StreamTokenizer和PrintWriter
StreamTokenizer这种方式只能读取数字和字符串,不能读取空格和其他字符,不推荐。(如果输入除空格和回车以外的字符,会无法识别,显示成null。同时如果要求输出的是字符,你的输入是数字开头,则字符会变成null;要求是输入数字却输出字母,那么数字会变成0)
PrintWriter类中包含print()、printf()。printf()可用于格式化输出,但速度最慢,write()速度最快。
PS:在最后刷新输出缓冲区,要加上flush(),否则什么都输出不了。
1.2.2 BufferedReader和BufferedWriter
两个都在java.io.*包中。
BufferedReader
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int s1 = in.read(); //读入一个字符,可读入空格回车
String s2 = in.readLine(); //读入一行数据,可读入空格
PS:在windows中按一下回车一共有两个字符“\n\r”,因而要用**两个read()来吸收回车;而只需要一个readLine()**吸收回车。
BufferedWriter
主要使用write()类进行输出,会抛出异常。当数据量大的时候一定要使用这个类进行输出,输出后不会自动换行。
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
write()不能直接输出int类型,会输出相应的ASCII码的字符。例如:输出65会显示A。当需要输出一个int变量时,可以使用Integer.toString(int a) 的方法,将其变成字符串形式输出;或者使用+拼接一个字符串。
2. 数组操作
2.1 数组的复制
2.1.1 数组的clone()
int[] a = {
2, 3, 5, 11, 66, 86, 43, 89, 77, 21, 54, 31};
int[] b = new int[20];
b = a.clone();
System.out.println(Arrays.toString(b));
//[2, 3, 5, 11, 66, 86, 43, 89, 77, 21, 54, 31]
2.1.2 System.arraycopy()(重点)
public static void arraycopy(Object src, int srcPos, Object dest, int desPos, int length);//src是源数组,srcPos是源数组的起始下标,dest是目标数组,desPos是目标数组下标,length是复制的数组元素个数
PS:新的数组多余的位置自动补0,且比clone()速度快。
int[] a = {
2, 3, 5, 11, 66, 86, 43, 89, 77, 21, 54, 31};
int[] b = new int[20];
System.arraycopy(a, 0, b, 0, 10);
System.out.println(Arrays.toString(b));
//[2, 3, 5, 11, 66, 86, 43, 89, 77, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
System.arraycopy(a, 0, b, 0, a.length);
System.out.println(Arrays.toString(b));
//[2, 3, 5, 11, 66, 86, 43, 89, 77, 21, 54, 31, 0, 0, 0, 0, 0, 0, 0, 0]
2.1.3 Arrays类的copyOf()和copyOfRange()
copyOf()
public static int[] copyOf(int[] original, int newLength);
//int[]可以是基本类型,也可以是对象类型, original是源数组,newLength是新数组长度
PS:这个b数组的长度是下面的自己定义的长度15,而不像System.arraycopy()中的b长度是一开始定义的长度。
b = Arrays.copyOf(a, 5);
System.out.println(Arrays.toString(b));
//[2, 3, 5, 11, 66]
b = Arrays.copyOf(a, 15);
System.out.println(Arrays.toString(b));
//[2, 3, 5, 11, 66, 86, 43, 89, 77, 21, 54, 31, 0, 0, 0]
copyOfRange()
public static char[] copyOfRange(char[] original, int from, int to);
//char[]可以是基本类型,也可以是对象类型, original是源数组,from是指定复制元素在源数组的起始下标,to是结束下标,不包括
b = Arrays.copyOfRange(a, 2, 7);
System.out.println(Arrays.toString(b));
//[5, 11, 66, 86, 43]
2.2 数组相关操作
Arrays.fill(); //填充数组
int[] arr = new int[5];
Arrays.fill(arr, 4); //给所有值赋值为4
System.out.println(Arrays.toString(arr));
//[4, 4, 4, 4, 4]
Arrays.fill(arr, 1, 4, 7);
System.out.println(Arrays.toString(arr)); //[1,4)下标1开始,4结束不包括4,赋值为7
//[4, 7, 7, 7, 4]
Arrays.sort(); // 数组排序
int[] arr1 =