Java基础

211 阅读4分钟

刷题过程中遇到的一些知识点

输入

Scanner in = new Scanner(System.in);
int num=in.nextInt();//接收数字,以空格或回车分割
in.nextLine();//nextInt()等与nextline()一起使用必须过滤回车
String str=in.nextLine();//接收一整行,包括空格
//读取一行文本,当遇到'\n'和'\r'结束
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
String s=bf.readLine();

第二种方法比第一种快,适合输入数据很长时使用

输出

多个结果中间用空格连接,结尾无空格

List<String> ls=List.of("a","b","c");
System.out.println(String.join(" ", ls));
		for (int i=0;i<n;i++) {
			for (int j=0;j<m-1;j++) {
				System.out.format("%d ", mat[i][j]);
			}
			System.out.format("%d\n", mat[i][m-1]);
		}

集合

Set

初始化

方法一

import java.util.HashSet;
import java.util.Set;
public class Main {
    public static void main(String[] args) {
        Set<Integer> s = new HashSet<>();
        s.add(1);
        s.add(2);
    }
}

方法二

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Main {
    public static void main(String[] args) {
        Set<Integer> s = new HashSet<>(Arrays.asList(1,2));
    }
}

类型转换

String转为char

//String.charAt(index)
//得到String中某一位置的char
String s="Hi!";
char c=s.charAt(2);
System.out.println(c);

//String.toCharArray()
//得到包含整个String的char数组
//这样可以通过索引访问String中任意位置的元素
char[] chars=s.toCharArray();
System.out.println(chars);
System.out.println(chars[2]);

char转为String

String s=String.valueOf('a');//效率最高
String s=String.valueOf(new char[] {'H','i','!'});
String s=Character.toString('b');
String s=new Character('c').toString();
String s=""+'d';//虽然简单,但是效率最低
String s=new String(new char[] {'e'});

String转为int

String s="123";
int x=Integer.valueOf(s);
System.out.println(x);

int转为String

int x=123;
String s=String.valueOf(x);
System.out.println(s);

List转为Array

List<Integer> list = List.of(12, 34, 56);
Integer[] array = list.toArray(new Integer[3]);
for (Integer n : array) {
	System.out.println(n);
}

Array转为List

Integer[] array = { 1, 2, 3 };
List<Integer> list = List.of(array);

字符转为Ascii码

char c='a';
int x=(int) c;
System.out.println(x);

Ascii码转为字符

int x=97;
char c=(char) x;
System.out.println(c);

数字字符转为整型数字

char c='1';
int x=c-48;
System.out.println(x);

排序

降序

Integer[] arr = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
Arrays.sort(arr,Collections.reverseOrder());

==和equals

==是判断两个变量是不是指向同一个内存空间

equals是判断两个变量指向的值是否相同

	Integer A=new Integer(5);
	Integer B=new Integer(5);
	System.out.println(A==B);//false
	System.out.println(A.equals(B));//true
	
	Integer aaa=5;
	Integer bbb=5;
	System.out.println(aaa==bbb);//true
	System.out.println(aaa.equals(bbb));//true

int a=10;
int b=10;
System.out.println(a==b);//true

String s1=new String("justice");
String s2=new String("justice");//和s1不同地址
String s3=s1;//和s1同一地址

System.out.println(s1==s2);//false
System.out.println(s1.equals(s2));//true
System.out.println(s1==s3);//true
System.out.println(s1.equals(s3));//true

大数

别忘记import java.math.BigInteger

Scanner sc=new Scanner(System.in);
BigInteger A=sc.nextBigInteger();//输入一个大整数
BigInteger B=BigInteger.TEN;//BigInteger中的常数
BigInteger C=BigInteger.valueOf(2);//用int赋初值
BigInteger D=new BigInteger("5");//用字符串构造大整数
BigInteger E=new BigInteger("1001", 2);//根据指定基数的字符串构造
System.out.println(E);
System.out.println(A.add(B));//加法
System.out.println(A.subtract(B));//减法
System.out.println(A.multiply(B));//乘法
System.out.println(A.divide(B));//除法
System.out.println(A.remainder(B));//取余
BigInteger[] dar=A.divideAndRemainder(B);//dar[0]=A/B,dar[1]=A%B
System.out.println(dar[0]+" "+dar[1]);
System.out.println(A.pow(3));//幂运算
System.out.println(A.or(B));//或
System.out.println(A.compareTo(B));//根据< = >返回-1 0 1

无穷大/小整数

int INF=int INF=Integer.MAX_VALUE;//2^31-1
int negINF=Integer.MIN_VALUE;//-2^31

保留小数

使用BigDecimal

BigDecimal bd=new BigDecimal(2.456);
bd=bd.setScale(2, RoundingMode.HALF_UP);//可选择多种保留方式,此种是四舍五入

使用String.format

double value=2.456;
System.out.println(String.format("%.2f", value).toString());

优先队列

每次从优先队列队首获取元素时,总是获取优先级最高的元素

自己定义元素的优先级,经常用于解决top K问题最小K个数

Queue<Integer> q=new PriorityQueue<> (k,(o1,o2)->o1-o2);
//第一个参数k是优先队列初始化大小
//第二个参数是一个lambda表达式,用于定义元素的优先级
//->前面的括号里是函数参数,->后是返回值,返回值<0为o1优先于o2

重写equals和hashCode

List重写equals

使用List里的contains方法会发现一些问题:

List<int[]> ls=new ArrayList<> ();
int[] a= {1,2};
int[] b= {1,2};
ls.add(a);
System.out.println(ls.contains(b));//false
List<int[]> ls=new ArrayList<> ();
int[] a= {1,2};
int[] b= a;
ls.add(a);
System.out.println(ls.contains(b));//true

两种结果不一样,因为contains方法比较的是两个对象引用,简而言之就是看两个对象是否地址相同。

查看ArrayList的contains源码可以发现其调用了equals方法,所以我们可以通过重写equals达到我们想要的效果。

class Point{
	int x;
	int y;
	public Point(int x,int y) {
		this.x=x;
		this.y=y;
	}
	@Override
	public boolean equals(Object obj) {
		Point p=(Point) obj;
		return this.x==p.x && this.y==p.y;
	}
}

Map重写equals和hashCode

使用Map时,如果我们放入的key是自己写的类,必须重写equals方法和hashCode方法

重写方法

正则表达式

廖雪峰Java正则表达式

移位运算

在计算机中,整数总是以二进制的形式表示。例如,int类型的整数7使用4字节表示的二进制如下: 00000000 00000000 00000000 00000111

可以对整数进行移位运算。对整数7左移1位得到整数14,左移两位得到整数28

int n = 7;
int a = n << 1; // 00000000 00000000 00000000 00001110 = 14
int b = n << 2; // 00000000 00000000 00000000 00011100 = 28
int c = n << 28;// 01110000 00000000 00000000 00000000 = 1879048192
int d = n << 29;// 11100000 00000000 00000000 00000000 = -536870912
System.out.println(Integer.toString(a, 2));
System.out.println(Integer.toBinaryString(b)); 
System.out.println(Integer.toBinaryString(c)); 
System.out.println(Integer.toBinaryString(d)); 

左移29位时,由于最高位变成1,因此结果变成了负数。 类似的,对整数7进行右移,结果如下:

int n = 7;       // 00000000 00000000 00000000 00000111 = 7
int a = n >> 1;  // 00000000 00000000 00000000 00000011 = 3
int b = n >> 2;  // 00000000 00000000 00000000 00000001 = 1
int c = n >> 3;  // 00000000 00000000 00000000 00000000 = 0

如果对一个负数进行右移,最高位的1不动,结果仍然是一个负数:

int n = -536870912;
int a = n >> 1; // 11110000 00000000 00000000 00000000 = -268435456
int b = n >> 2; // 11111000 00000000 00000000 00000000 = -134217728
int c = n >> 28; // 11111111 11111111 11111111 11111110 = -2
int d = n >> 29; // 11111111 11111111 11111111 11111111 = -1

还有一种无符号的右移运算>>>,不管符号位,右移后高位总是补0。因此,对一个负数进行>>>,它会变成正数:

int n = -536870912;
int a = n >>> 1;  // 01110000 00000000 00000000 00000000 = 1879048192
int b = n >>> 2;  // 00111000 00000000 00000000 00000000 = 939524096
int c = n >>> 29; // 00000000 00000000 00000000 00000111 = 7
int d = n >>> 31; // 00000000 00000000 00000000 00000001 = 1

byteshort类型进行移位时,会首先转换为int再进行移位。 左移实际上就是不断地×2,右移实际上就是不断地÷2。

在位运算的题目中,经常通过将整数右移i位,再 & 1,来获得整数的第i位。