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 = {3, 5, 4, 1, 7};
Arrays.sort(arr1, 0, 3);
System.out.println(Arrays.toString(arr1));
//按小标0开始,3结束不包括3排序 [3, 4, 5, 1, 7]
Arrays.sort(arr1);
System.out.println(Arrays.toString(arr1));
//按数字从小到大 [1, 3, 4, 5, 7]
String[] arr2 = {"z", "a", "C"};
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));
//按ASCII码从小到大 [C, a, z]
Arrays.sort(arr2, String.CASE_INSENSITIVE_ORDER);
System.out.println(Arrays.toString(arr2));
//按字母表顺序,忽略大小写 [a, C, z]
Arrays.sort(arr2, String.CASE_INSENSITIVE_ORDER);
Collections.reverse(Arrays.asList(arr2));
System.out.println(Arrays.toString(arr2));
//按字母表逆序,忽略大小写 [z, C, a]
Arrays.toString(); //将数组的内容全部打印出来
Arrays.equals(); //比较数组元素是否相等
Arrays.binarySearch(); //二分查找找指定元素的下标,数组一定要是排好序的,否则会出错。找到元素,只会返回最后一个位置。
数组容量如果不够用可以使用Arrays.copyOf()进行扩充。
3. 进制转换、保留小数
3.1 进制转换
十进制转其他进制
函数:Integer.toString(k, r),将十进制的数k转换为r进制的数,返回一个String。
int k = 17;
int r = 2;
System.out.println(Integer.toString(k, r)); //转成r进制 10001
r = 8;
System.out.println(Integer.toString(k, r)); //转成r进制 21
r = 16;
System.out.println(Integer.toString(k, r)); //转成r进制 11
其他进制转换成十进制
函数:Integer.parseInt(str, r), 将r进制的数字字符串str转换成十进制,并返回十进制的数。
System.out.println(Integer.parseInt("10001", 2)); //17
System.out.println(Integer.parseInt("21", 8)); //17
System.out.println(Integer.parseInt("11", 16)); //17
3.2 保留小数
函数:String.format()
double a = 121.4324654;
double b = 246.24098792;
System.out.println(String.format("%.2f", a)); //121.43
System.out.println(String.format("%.3f", b)); //246.241
4. 常用数据类型
4.1 byte
- 8位
- 最小值是-128(-2^7), 最大值是127(2^7 - 1)
- 默认值为0
4.2 short
- 16位
- 最小值是-32768(-2^15), 最大值是32767(2^15 - 1)
- 默认值为0
4.3 int
- 32位
- 最小值是-2^31, 最大值是2^31 - 1
- 一般整型变量默认为int类型,默认值为0
4.4 long
- 64位
- 最小值是-2^63, 最大值是2^63 - 1
- 默认值为0L
4.5 float
- 32位,单精度
- 默认值为0.0f
4.6 double
- 64位,双精度
- 浮点数的默认类型是double类型,默认值为0.0d
4.7 boolean
- boolean数据类型表示一位的信息
- 只有两个取值:true和false
- 默认值为false
4.8 char
- 16位
- 最小值是‘\u0000’(即为0),最大值是‘\uffff’(即为65535)
输入
单个字符
Scanner in = new Scanner(System.in);
char ch = in.next().charAt(3); //wsldxa
System.out.println(ch); //d
字符数组
char[] chars = new char[20];
String s = in.next(); //wdksssa
chars = s.toCharArray();
System.out.println(chars); //wdksssa
输出
char[] chars = new char[20];
String s = in.next(); //wdksssa
chars = s.toCharArray();
System.out.println("s = :" + s); //s = :wdksssa
System.out.println("chars = :" + chars); //chars = :[C@7ea987ac
System.out.println(chars); //wdksssa
出现输出chars不同的结果是println方法的重载问题导致的。因为第一次中的"chars = :"把数组变成了String类型了,第一次调用的参数是String类型的,第二次调用的参数是char[]数组类型的。
4.9 基本数据类型与包装类
基本数据类型转换成包装类
int i = 77;
Integer in = new Integer(i);
System.out.println(in.toString());
Integer it = new Integer("12121"); //必须为数字的字符串,加字母会运行出错
System.out.println(it.toString());
包装类转换成基本数据类型
Integer integer = new Integer(17);
int a = integer.intValue();
System.out.println(a + 1); //18
基本数据类型、包装类转换成String
//方式一
int num = 12;
String s = num + "";
System.out.println(s); //12
//方式二
double d = 23.9;
String s1 = String.valueOf(d);
System.out.println(s1); //23.9
String转换成基本数据类型、包装类
String s = "21"; //只能写数字
int i = Integer.parseInt(s);
System.out.println(i + 1);
String s1 = "true"; //只有写true输出的才是true
boolean b = Boolean.parseBoolean(s1);
System.out.println(b);
自动装箱:基本数据类型转换成包装类;自动拆箱:包装类转换成基本数据类型。
4.10 String
字符串比较
-
使用equals()比较内容是否一样(==比较的是地址)
-
忽略大小写比较是equalsIgnoreCase()
-
是否包含子串:contains()
String s = "ascdkxkcc"; System.out.println(s.contains("as")); //true System.out.println(s.contains("awww")); //false
-
查看子串是否在母串的开始:startsWith()
String s = "ascdkxkcc"; System.out.println(s.startsWith("asc")); //true System.out.println(s.startsWith("asca")); //false
-
查看子串是否在母串的最后:endsWith()
String s = "ascdkxkcc"; System.out.println(s.endsWith("kcc")); //true System.out.println(s.endsWith("kc")); //false
-
找子串第一次出现的下标,从下标 0开始,没有找到-1:indexOf()
String s = "ascdkxkcc"; System.out.println(s.indexOf("kcc")); //6 System.out.println(s.indexOf("kww")); //-1
-
找子串最后出现的下标:lastIndexOf()
String s = "ascdkcxkcc"; System.out.println(s.lastIndexOf("sc")); //1 System.out.println(s.lastIndexOf("kc")); //7
-
提取子串:substring()
String s = "ascdkcxkcc"; System.out.println(s.substring(1)); //scdkcxkcc System.out.println(s.substring(1, 5)); //从下标1到5(不包括5),scdk
-
去除首位空白字符
- trim():去除字符串首尾空白字符,空白字符包括空格,\t, \r, \n
- strip():和trim()不同的是中文的空格字符\u3000也会被移除
-
判断字符串
-
判断字符串是否为空:isEmpty()
System.out.println("".isEmpty()); //true 字符串长度为0 System.out.println(" ".isEmpty());//false 字符串长度不为0
-
判断字符串是否是空白字符串:isBlank()(只包含空白字符)
-
-
替换:replace(),返回一个新字符串
String s = "asedadssssse"; String s1 = s.replace('s', 'w');//单个字符换单个字符,不能单个字符换多个字符 String s2 = s.replace("da", "ww"); System.out.println(s1); //awedadwwwwwe System.out.println(s2); //awedadwwwwwe
-
分割字符串:split(), 返回是一个字符串数组
String s = "ab,de,sffd"; String[] s1 = s.split(","); for (int i = 0; i < s1.length; i++) { System.out.println(s1[i]); } //ab //de //sffd String s2 = "ab\\sa\\svg\\ed"; String[] s3 = s2.split("\\\\"); //特殊情况,以\为分割线 for (int i = 0; i < s3.length; i++) { System.out.println(s3[i]); } //ab //sa //svg //ed //需要加双斜线的:+、*、$、^ String s4 = "av+sx+dj"; String[] s5 = s4.split("\\+"); //以+为分割线 //多个符号作为分隔符,使用多个分隔符则需要借助|符号 String s6 = "ab,dji+@sdji"; String[] s7 = s6.split(",|\\+|@"); //以, + @为分隔符
-
拼接字符串:join(), 用指定的字符串连接字符串数组,返回一个字符串
String s = "ab,de,sffd"; String[] s1 = s.split(","); int len = s1.length; for (int i = 0; i < len; i++) { System.out.println(s1[i]); } String str = String.join("**", s1); System.out.println(str); //ab**de**sffd //ab //de //sffd
-
Integer有个getInteger(String)方法,它不是将字符串转换成int,而是把该字符串对应的系统变量转换成Integer。
Integer.getInteger("java.version"); //版本号 11
-
字符串与char[]数组相互转换
new String(char[])是创建了一个新的String实例,并不会直接引用传入的char[]数组,因而修改外部的char[]不会影响String。
char[] ch = "HelloJava".toCharArray(); //String ---> char[] String s = new String(ch); //char[] ---> String
StringBuffer和StringBuilder
两者使用没什么区别,由于StringBuilder相较于StringBuffer有速度优势,所以多数情况下使用StringBuilder。
-
字符串连接:append()
StringBuilder strB = new StringBuilder(); System.out.println(strB.append("asa").append("seewaa")); //asaseewaa
-
将第i个代码单元设置成c(理解成替换):setCharAt(int i, char c)
strB.setCharAt(2, 'g'); System.out.println(strB); //asgseewaa
-
在指定位置之前插入字符(串):insert(int offset, String s) / insert(int offset, char c)
System.out.println(strB.insert(2, "wld")); //aswldaseewaa
-
删除起始位置(含)到结尾位置(不含)之间的字符串:delete (int startIndex, int endIndex)
System.out.println(strB.delete(1, 4)); //aeewaa
String与StringBuilder相互转换
String s = "seesaw";
StringBuilder sb = new StringBuilder(s); //String ---> StringBuilder
String ss = sb.toString(); //StringBuilder ---> String
System.out.println(ss);
使用基本原则
- 操作少量数据:String
- 单线程操作大量数据:StringBuilder
- 多线程操作大量数据:StringBuffer
在使用StringBuffer类时,每次都会对对象本身进行操作,而不是生成新的对象,所以在需要对字符串进行修改推荐使用StringBuffer。StringBuilder不是线程安全的(不能同步访问),但有速度优势。
length()、length属性、size()区别
- length()是针对字符串来说的。
- length属性是针对数组来说的。
- size()是针对泛型集合来说的。
5. 位运算
- 按位取反(~):将0变1,1变0
- 按位与(&):同时为1才为1,否则为0
- 按位异或(^):不同为1,相同为0 (任何数与0异或都是它本身)
- 按位或(|):只要有1结果就是1,否则为0
在计算机中,整数是按原码存放的,负数是按补码存放的。整数的补码和原码相同,负数的补码等于原码取反后再加1。
位运算的技巧
-
交换两数
int a = 121; int b = 343; a = a ^ b; b = a ^ b; a = a ^ b; //两个相同的数异或之后结果是0,任何数与0异或是它本身。 //异或运算支持交换律和结合律
-
找出没有重复的数:给出一组整形数据,这些数据中有一个数只出现了一次,让找出这个数。
public static int find(int[] arr){ /*int temp = arr[0]; for (int i = 1; i < arr.length; i++) { temp = temp ^ arr[i]; } return temp;*/ int x = 0; for(int i : arr){ x = x ^ i; } return x; } //相同的数异或是0,0和任何数异或是它本身
-
求两个数的平均值
(a & b) + ((a ^ b) >> 1) //防止两数相加超出类型范围
-
判断一个数是否是2的整数次幂
int n = 1024; //方法一: if((n & (n - 1)) == 0){ System.out.println("YES"); }else{ System.out.println("NO"); } //如果是负数和0要单独判断 //方法二: if((n & (-n)) == n){ System.out.println("YES"); }else{ System.out.println("NO"); }
-
消除二进制中的最后一个1
n & (n - 1)
6. 大数处理
整数用BigInteger,小数用BigDecimal。
BigInteger常用方法
-
求绝对值abs()
String s = "-32542357682"; BigInteger big = new BigInteger(s); BigInteger bigs = big.abs(); System.out.println(bigs); //32542357682
-
两数相加add()
String s = "-3848432939"; String ss = "7959532028"; BigInteger bs = new BigInteger(s); BigInteger bss = new BigInteger(ss); BigInteger add = bs.add(bss); System.out.println(add); //4111099089
-
两数相减substract()
-
两数相乘multiply()
-
两数相除divide()
-
求相反数negate()
-
求余数remainder() (在小数中可以使用)
-
求模mod() (不能在小数中使用)
-
求幂次方pow()
-
返回大整数的double值doubleValue() (也有类型对应:floatValue、intValue、longValue)
String s = "357425778"; String ss = "34546"; BigInteger bs = new BigInteger(s); BigInteger bss = new BigInteger(ss); double d = bs.doubleValue(); double dd = bss.doubleValue(); System.out.println(d); //3.57425778E8 //当数组长度超过7位,会自动采用科学计数法输出 System.out.println(dd); //34546.0
-
两数中的最大值max()
-
两数中的最小值min()
-
求两数的最大公约数gcd()
-
两数的按位与and()
-
两数的按位或or()
-
两数的异或xor()
-
将当前数左移n位shiftLeft():当前数乘以n个2
-
将当前数右移n位rightLeft():当前数除以n个2
BigInteger进制转换
十进制转其他进制
String string1 = new BigInteger("20", 10).toString(2);
System.out.println("十进制的20转换成二进制是:"+string1);
String string2 = new BigInteger("20", 10).toString(8);
System.out.println("十进制的20转换成八进制是:"+string2);
String string3 = new BigInteger("20", 10).toString(16);
System.out.println("十进制的20转换成十六进制是:"+string3);
//十进制的20转换成二进制是:10100
//十进制的20转换成八进制是:24
//十进制的20转换成十六进制是:14
其他进制转换十进制
String string4 = new BigInteger("110", 2).toString(10);
System.out.println("二进制的110转换成十进制是:"+string4);
String string5 = new BigInteger("110", 8).toString(10);
System.out.println("八进制的110转换成十进制是:"+string5);
String string6 = new BigInteger("110", 16).toString(10);
System.out.println("十六进制的110转换成十进制是:"+string6);
//二进制的110转换成十进制是:6
//八进制的110转换成十进制是:72
//十六进制的110转换成十进制是:272
BigDecimal
小数位数
Scanner cin = new Scanner(System.in);
BigDecimal big ;
big = cin.nextBigDecimal();
System.out.println(big.scale()); //scale() 获取小数位数;若是整数则为负数,表示的末尾的0个数
System.out.println(big);
big = big.stripTrailingZeros(); // 去掉小数末尾的无用0
System.out.println(big.scale());
System.out.println(big);
对一个BigDecimal设置它的scale,如果精度比原始值低,那么按照指定的方法进行四舍五入或者直接截断。
BigDecimal d1 = new BigDecimal("123.456789");
BigDecimal d2 = d1.setScale(4, RoundingMode.HALF_UP); // 四舍五入
BigDecimal d3 = d1.setScale(4, RoundingMode.DOWN); // 直接截断
System.out.println(d2); //123.4568
System.out.println(d3); //123.4567
对BigDecimal做加、减、乘时,精度不会丢失,但是做除法时,存在无法除尽的情况,这时,就必须指定精度以及如何进行截断。
BigDecimal d1 = new BigDecimal("123.456");
BigDecimal d2 = new BigDecimal("23.456789");
BigDecimal d3 = d1.divide(d2, 10, RoundingMode.HALF_UP); //保留10位小数并四舍五入
BigDecimal d4 = d1.divide(d2); // 报错:ArithmeticException,因为除不尽
对BigDecimal做除法的同时求余数。调用divideAndRemainder()方法时,返回的数组包含两个BigDecimal,分别是商和余数,其中商总是整数,余数不会大于除数。
BigDecimal n = new BigDecimal("12.345");
BigDecimal m = new BigDecimal("0.12");
BigDecimal[] dr = n.divideAndRemainder(m);
System.out.println(dr[0]); // 102
System.out.println(dr[1]); // 0.105
在比较两个BigDecimal的值是否相等时,要特别注意,使用equals()方法不但要求两个BigDecimal的值相等,还要求它们的scale()相等。
必须使用compareTo()方法来比较,它根据两个值的大小分别返回负数、正数和0,分别表示小于、大于和等于。总是使用compareTo()比较两个BigDecimal的值,不使用equals()。
BigDecimal d1 = new BigDecimal("123.456");
BigDecimal d2 = new BigDecimal("123.45600");
System.out.println(d1.equals(d2)); // false,因为scale不同
System.out.println(d1.equals(d2.stripTrailingZeros()));// true,因为d2去除尾部0后scale变为2
System.out.println(d1.compareTo(d2)); // 0
7.日期时间
Date类
使用当前的日期和时间来初始化对象。
Date date = new Date();
System.out.println(date);
接收一个参数,该参数是从1970.1.1起的毫秒数
Date date = new Date(10000000);
System.out.println(date);
1.日期比较
Java使用以下三种方法来比较两个日期:
- 使用getTime()来获取两个日期,然后比较这两个值。
- 使用before()、after()、equals()。
- 使用compare To(),它是由Comparable接口定义的,Date实现了这个接口。
2.日期和时间的格式化编码
使用SimpleDateFormat格式化日期,它允许你选择任何用户自定义日期时间格式来运行。
Date date = new Date(120000000);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(date)); //1970-01-02 17:20:00
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss");
System.out.println(sdf2.format(date)); //1970年01月02日 17时20分00
ps:有的格式大写,有的格式小写。例如:MM是月份,mm是分;HH是24小时制,hh是12小时制。
3.System类中的currentTimeMillis()
返回一个long型的数值,这个数值是当下时间与1970.1.1零时的时间差,以毫秒为单位。
long t = System.currentTimeMillis();
System.out.println(t);
4.printf格式化日期
使用两个字母格式,它以%t开头并且以下面中的一个字母结尾。
Date date = new Date();
//c的使用: 全部日期和时间信息:星期一 一月 24 17:41:02 CST 2022
System.out.printf("全部日期和时间信息:%tc%n" ,date);
//f的使用: 年-月-日格式:2022-01-24
System.out.printf("年-月-日格式:%tF%n" ,date);
//d的使用: 月/日/年格式:01/24/22
System.out.printf("月/日/年格式:%tD%n" ,date);
//r的使用: HH:MM:SS PM格式(12时制):05:41:02 下午
System.out.printf("HH:MM:SS PM格式(12时制):%tr%n" ,date);
//t的使用: HH:MM:SS格式(24时制):17:41:02
System.out.printf("HH:MM:SS格式(24时制):%tT%n" ,date);
//R的使用: HH:MM格式(24时制):17:41
System.out.printf("HH:MM格式(24时制):%tR" ,date);
5.字符串转换成时间
SimpleDateFormat 类有一些附加的方法,特别是parse(),它试图按照给定的SimpleDateFormat 对象的格式化存储来解析字符串。format()将Date对象格式化为字符串。
String s = "2022年1月24日";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");//用来解析字符串
Date date = null;
try {
date = sdf.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd"); //按照格式输出时间字符串
System.out.printf(sdf2.format(date)); //2022/01/24
Calendar类
抽象类,可以设置(加减)和获取日期数据的特定部分。
Calendar的月份是从0开始的,但日期和年份是从1开始的。周日–周六对应1–7.
1.创建对象
当前日期的Calendar对象
Calendar c = Calendar.getInstance();//默认是当前日期,创建一个代表系统当前日期的Calendar对象
指定日期的Calendar对象:先创建对象,再设定该对象的年月日参数来完成。
//创建一个代表2022年1月24日的Calendar对象
Calendar c1 = Calendar.getInstance();
c1.set(2022, 1 - 1, 24);
2.信息的设置
- set(int year, int month, int date)
c1.set(2022 ,1, 24);//把Calendar对象c1的年月日分别设这为:2022、1、24
c1.set(Calendar.DATE, 10);//把 c1对象代表的日期设置为10号,其它所有的数值会被重新计算
-
add()
c1.add(Calendar.DATE, 10); //把c1对象的日期加上10,也就是c1也就表示为10天后的日期,其它所有的数值会被重新计算
-
get()
Calendar c1 = Calendar.getInstance(); // 获得年份 int year = c1.get(Calendar.YEAR); // 获得月份 int month = c1.get(Calendar.MONTH) + 1; //因为是从0开始的,所以要加1 // 获得日期 int date = c1.get(Calendar.DATE); // 获得小时 int hour = c1.get(Calendar.HOUR_OF_DAY); // 获得分钟 int minute = c1.get(Calendar.MINUTE); // 获得秒 int second = c1.get(Calendar.SECOND); // 获得星期几(注意(这个与Date类是不同的):1代表星期日、2代表星期1、3代表星期二,以此类推) int day = c1.get(Calendar.DAY_OF_WEEK);
求两个时间间隔
public static long getStartToEndTime(String start,String end) throws Exception{
String startTime = start;
String endTime = end;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //时间格式根据需要变动
Date d1 = format.parse(startTime);
Date d2 = format.parse(endTime);
long diff = Math.abs(d1.getTime() - d2.getTime());
System.out.println("相差 " + diff + " 毫秒");
long diffSeconds = diff / 1000 % 60; //秒
long diffMinutes = diff / (60 * 1000) % 60; //分钟
long diffHours = diff / (60 * 60 * 1000) % 24; //小时
long diffDays = diff / (24 * 60 * 60 * 1000); //天
System.out.print("两个时间相差:");
System.out.print(diffDays + " 天, ");
System.out.print(diffHours + " 小时, ");
System.out.print(diffMinutes + " 分钟, ");
System.out.println(diffSeconds + " 秒.");
System.out.println("相差 " + diffDays / 365 + " 年");
return diff;
}
求日期的天数、周数、星期数
ps:这里的第几周不是按平常的一周七天计算的,是按照日历中的一行来算的。
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒SSS毫秒");
System.out.println(sdf.format(date));
SimpleDateFormat sdf2 = new SimpleDateFormat("E 一年中的第w周、第D天 一个月中的第W周的周F 一天中的24制的第k小时(点)12制的第K小时(点)");
System.out.println(sdf2.format(date));
//2022年01月24日 19时09分00秒489毫秒
//星期一 一年中的第5周、第24天 一个月中的第5周的周4 一天中的24制的第19小时(点)12制的第7小时(点)