11. 常用类
11.1 包装类
8种基本数据类型都有对应的应用类型——包装类,其中和数字相关的包装类都继承了Number类,下图黄色
11.1.1 装箱/拆箱
装箱:基本数据类型 ——> 包装类
拆箱:包装类 ——> 基本数据类型
在jdk5之前只能手动装箱和拆箱,jdk5(含jdk5)之后自动装箱和拆箱
//手动装箱
int num = 66;
//1
Integer integer = new Integer(num);
//2
Integer integer1 = Integer.valueOf(num);
//手动拆箱
int num1 = integer.intValue();
//自动装箱
int num2 = 77;
Integer integer2 = num2;//底层还是使用Integer.valueOf(num)
//自动拆箱
int num3 = integer2;//底层还是使用integer.intValue()
包装类和String转换
以Integer举例,其他类似
// Integer -> String
Integer integer = 100;
String str = integer + "";
String str1 = integer.toString();
String str2 = String.valueOf(integer);
// String -> Integer
Integer num = new Integer(str);
Integer num1 = Integer.valueOf(str1);
Integer num2 = Integer.parseInt(str2);
Integer类和Character类常用方法
- Integer.MIN_VALUE:返回最小值
- Integer.MAX_VALUE:返回最大值
- Character.isDigit(‘a’):判断是不是数字
- Character.isLetter(‘a’):判断是不是字母
- Character.isUpperCase(‘a’):判断是不是大写
- Character.isLowerCase(‘a’):判断是不是小写
- Character.isWhitespace(‘a’):判断是不是空格
- Character.toUpperCase(‘a’):转成大写
- Character.toLowerCase(‘A’):转成小写
细节讨论
-
自动装的底层还是使用Integer.valueOf(num)
-
自动拆箱底层还是使用integer.intValue()
-
valueOf()方法参数在-128~127范围内不会创建新对象
// valueOf的int参数方法源码 public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
所以下面代码应该会有全新的理解
Integer x = 1; // 本质是Integer.valueOf(1),不会创建新的Integer对象 Integer y = 128; // 本质是Integer.valueOf(128),会创建新的Integer对象
-
包装类和基本数据类型运算,会先自动拆箱
Integer x = 128; // 本质是Integer.valueOf(128) int y = 128; // 比较时x会先自动拆箱, // y.intValue()得到int类型数值再与x运算 System.out.println(x == y); // true
两个数据比较,只要其中有一个是基本数据类型,==就是比较值的大小
int num = 10;
Integer in = new Integer(10);
System.out.println(num == in);//输出true
三目运算符细节:
Object obj1 = true ? new Integer(1) : new Double(2.0);
System.out.println(obj1); // 输出结果是1.0
三目运算是一个整体,所以int和double类型进行计算时,int类型会转成double类型
11.2 String类
String对象用于保存字符串,也就是一组字符序列。
字符串常量对象是用双括号括起来的字符序列,如:“hello”,“你好”。
字符串的字符使用Unicode字符编码,一个字符(不区分字母和汉字)占两个字节。
String类是final的,不能被继承。
String有属性private final char value[];用于存放字符串内容,value是final类型的,不可以修改:即value不能指向新的地址,但是数组中的元素可以改变。
String类中重载了很多构造器,下面举几个常用用的
String s1 = new String();//w
String s1 = new String(Stirng original);
String s1 = new String(char[] a);
String s1 = new String(char[] a, int startIndex, int count);
String实现了Serializable和Comparable接口,实现Serializable接口说明String可以串行化,可以在网络传输;实现Comparable接口说明String对象可以比较大小。
两种创建String对象方式:
- 直接赋值:String s1 = “jack”;
- 调用构造器:String s2 = new String(“tom”);
方式一:先从常量池查看是否有”jack”数据空间,如果有,直接指向;如果没有则重新创建,然后指向。name最终指向的是常量池的空间地址。
方式二:现在堆中创建String对象,String对象里面有value属性,查看常量池是否有”tom”数据空间,如果有,直接通过value指向;如果常量池中没有”tom”,则重新创建,然后通过value指向,s2最终指向的是堆中的空间地址。
细节:
-
字符串常量相加优化:String a = “hello” + “abc”;并不会创建两个字符串,再拼接创建第三个字符串,而是直接优化为String a = “helloabc”。只需要创建一个字符串就可以了
String a = "hello" + "abc";
-
字符串变量相加实质过程
- 先创建一个StringBuilder sb = StringBuilder ()
- 执行sb.append(“hello”);
- 执行sb.append(“abd”);
- Stirng str3 = sb.toString()
- 最后str3指向的是堆中的对象,(String)value[] -> “helloabc”
String str1 = "hello"; String str2 = "abc"; String str3 = str1 + str2;
-
练习题,易错点:在change方法中对局部变量str修改,不会影响成员变量的str
public class StringExercise1 { String str = new String("世界属于三体"); final char[] ch = {'j','a','v','a'}; public void change(String str, char ch[]){ str = "java";//String类的str引用指向一个新String对象,"java" ch[0] = 'h'; } public static void main(String[] args) { StringExercise1 se = new StringExercise1(); se.change(se.str,se.ch); System.out.print(se.str + ","); // 世界属于三体, System.out.println(se.ch); // hava } }
Strig类常见方法:
-
equals //区分大小写,判断内容是否相等
String string = "abc"; System.out.println(string.equals("abc")); //源码: public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
-
equalslgoreCase //忽略大小写的判断内容是否相等
System.out.println(str.equalsIgnoreCase("ABC"));
-
length //获取字符的个数,字符串的长度
System.out.println(str.length());
-
indexOf //获取字符在字符串中第一次出现的索引,从0开始,如果找不到,返回-1
System.out.println(str.indexOf('b')); System.out.println(str.indexOf("bc"));
-
lastIndexOf //获取字符在字符串中最后一次出现的索引,从0开始,如果找不到,返回-1
String str = "dshghafdafda"; System.out.println(str.lastIndexOf("hg"));
-
substring //截取指定范围的子串
// 从2号索引到结束字符串,包括2号 System.out.println(str.substring(2)); // 从0号索引到5号索引,包括0,不包括5 System.out.println(str.substring(0,5));
-
trim //去前后空格
String str = " fdsfdff "; System.out.println(str); System.out.println(str.trim());
-
charAt //获取某索引处的字符,注意不能使用Str[index]这种方式
System.out.println(str.charAt(2));
-
toUpperCase:小写转大写
String str = "acb"; System.out.println(str.toUpperCase());
-
toLowerCase:大写转小写
String str = "ABC"; System.out.println(str.toLowerCase());
-
concat:将指定的字符串连接到该字符串的末尾
System.out.println(str.concat("test"));
-
replace:替换字符串
String str3 = "我爱学Java"; System.out.println(str3.replace("学Java","睡觉")); // 我爱睡觉
-
split:分割字符串
String str = "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦"; String[] strArr = str.split(","); for (String s : strArr) { System.out.println(s); }
-
compareTo:比较两个字符串的大小,比较方法:挨个字符比较,直到遇到两个不同,返回调用者的字符减去参数的字符的值,如果直到一个字符串比较完都全部相同,就返回调用者字符串的长度减去参数字符串的长度
String s1 = "abcd"; String s2 = "abcd"; System.out.println(s1.compareTo(s2)); // 0
// compareTo方法 源码 public int compareTo(String anotherString) { int len1 = value.length; int len2 = anotherString.value.length; int lim = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int k = 0; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; } k++; } return len1 - len2; }
-
toCharArray:转换成字符数组
char ch[] = str.toCharArray();
-
intern:返回在常量池中和自身字符串值相等(用equals方法判断相等)的字符串地址,如果常量池中没有,则在常量池中创建这样字符串返回
-
format:格式字符串
// %s字符串 %c字符 %d整形 %f浮点型 String format = "%s今天早上吃了%d个馒头,因为%s考了%.2f分"; System.out.println(String.format(format,"小明",100,"小明",98.5));
11.3 StringBuffer
java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删。StirngBufferStingBuffer是一个final类,不能被继承。
StringBuffer的直接父类是AbstractStringBuilder,还实现了Serializable接口,即StringBuffer的对象可以串行化
在父类中,AbstractStringBuilder有属性char[] value,不是final,所以value数组存放的字符串内容,是引用放在堆中的字符数组
因为StringBuffer字符内容是存在char[] value中,所以在修改字符串时不用每次都更换地址(即不是每次都创建新对象),所以效率高于Strng
构造器:
-
无参构造器:创建一个大小为16的char[],用于存放字符内容
StringBuffer stringBuffer = new StringBuffer();
-
int类型参数构造器:通过构造器指定char[]的大小
StringBuffer stringBuffer = new StringBuffer(100);
-
String类型构造器:通过给一个String创建StringBuffer,char[]大小就是str.length() + 16
StringBuffer stringBuffer = new StringBuffer("hello");
StringBuffer和String相互转换:
-
String转StringBuffer
String string = "蜜雪冰城甜蜜蜜"; StringBuffer stringBuffer1 = new StringBuffer(string);//对string没有影响 // 法二 StringBuffer stringBuffer2 = new StringBuffer(); stringBuffer2.append(string);
-
StringBuffer转Stirng
StringBuffer stringBuffer = new StringBuffer("你好啊"); // 法一 String str = stringBuffer.toString(); // 法二 String str1 = new String(stringBuffer);
StringBuffer常用方法:
- append:增加字符串
stringBuffer.append("aaa");
stringBuffer.append("你好啊");
stringBuffer.append(",我是你的好朋友");
-
delete:删除,包括第一参数,不包括第二个参数
// 删除第2个到第3个字符 stringBuffer.delete(2,4); // [2,4)
-
replace:替换,替换位置包括第一参数,不包括第二个参数
// 将第0个到第1个元素替换为"这个世界" stringBuffer.replace(0,2,"这个世界"); // [0,2)
-
indexOf:查找字串第一次出现索引,找不到返回-1
// 查找"世界"第一次出现的索引 System.out.println(stringBuffer.indexOf("世界"));
-
insert:在索引位置插入字符串,后面自动后移
// 在索引2的位置插入"肮脏的" System.out.println(stringBuffer.insert(2,"肮脏的"));
-
length 获取长度
System.out.println(stringBuffer.length());
一些细节:
-
关于append方法:
String str = null; StringBuffer sb = new StringBuffer(); sb.append(str); System.out.println(sb.length); // 输出结果 4
结果分析:第三行把null作为append方法的参数添加到sb的后面,在append方法中,调用父类AbstractStringBuilder的append方法,父类append方法首先判断传入的对象是否为空,为空的话返回 appendNull方法返回的AbstractStringBuilder对象,在appendNull方法中,把null作为字符串放在value后面,返回AbstractStringBuilder类。
源码:
// StringBuffer的append方法源码 public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } // AbstractStringBuilder的append方法源码 public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; } // AbstractStringBuilder的appendNull方法源码 private AbstractStringBuilder appendNull() { int c = count; ensureCapacityInternal(c + 4); final char[] value = this.value; value[c++] = 'n'; value[c++] = 'u'; value[c++] = 'l'; value[c++] = 'l'; count = c; return this; }
-
关于构造器
String str = null; StringBuffer stringBuffer = new StringBuffer(str);//报空指针异常,NullPointerException
结果分析,第二行把null对象作为参数传入StringBuffer的有参构造器中,在StringBuffer的有参构造器中调用一个null的length,报错
源码:
public StringBuffer(String str) { super(str.length() + 16); append(str); }
11.4 StringBuilder
StringBuilder也是一个可变的字符序列,StringBuilder和StringBuffer继承了相同的类、实现了相同的接口,所以提供和StringBuffer兼容的API
StringBuilder的方法没有做互斥处理,即没有synchronized关键字
但是StringBuilder不保证同步(StringBuilder不是线程安全),该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用StringBuilder,应为在大多数情况下,StringBuilder比StringBuffer要快
String、StringBuffer和StringBuilder的区别
- StringBuffer和StringBuilder非常相似,均代表可变的字符序列,而且方法也一样
- String:不可变字符序列,每次修改都创建新对象,效率低,但复用率高。一般用在字符串很少修改,被多个对象引用的情况,比如配置信息
- StringBuffer:可变字符序列,效率较高(增删),线程安全。一般用在字符串存在大量修改操作,且是多线程的情况
- StringBuilder;可变字符序列,效率最高,线程不安全。一般用在字符串存在大量修改操作,且是单线程的情况
11.5 Math
Math类包含用于执行基本数学运算的方法,方法均为静态方法。
常用方法:
-
abs 绝对值
// abs 绝对值 int long float double int abs = Math.abs(-9); System.out.println(abs); // 9
-
pow 求幂
// pow 求幂 double->double double pow = Math.pow(2.0, 4.0); // 2^4 = 16.0 System.out.println(pow);
-
ceil 向上取整,返回>=该参数的最小整数
// ceil 向上取整 double->double double ceil = Math.ceil(5.6); System.out.println(ceil); // 6.0
-
floor 向下取整,返回<=该参数的最大整数
// floor 向下取整 double->doubledouble floor = Math.floor(5.6); System.out.println(floor); // 5.0
-
round 四舍五入
// round 四舍五入 float->int, double->longlong round = Math.round(5.8); System.out.println(round); // 6
-
sqrt 求开方
// sqrt 求开方 double->double double sqrt = Math.sqrt(9.0); System.out.println(sqrt); // 3.0
-
random 获取随机数【0,1)
// random 求随机数 [0,1) double random = Math.random(); System.out.println(random); // 0.05989661558702131 //获取a-b之间的整数,包括a和b int num = (int)(Math.random()*(b-a+1));
-
min 两数取小
// min 两数取小 int long float double int min = Math.min(5, 8); System.out.println(min); // 5
-
max 两数取大
//max 两数取大 int long float double int max = Math.max(9,54); System.out.println(max); // 54
11.6 Arrays
Array里面包含了一系列静态方法,用于管理或操作数组
-
toString:返回数组的字符串形式
// toString 把数组转为字符串 Integer[] arr = {7, -5, 28, 34, 10, -51, 62}; System.out.println(Arrays.toString(arr));//[7, -5, 28, 34, 10, -51, 62]
-
sort:排序
// 排序 正序 Integer[] arr = {7, -5, 28, 34, 10, -51, 62}; Arrays.sort(arr); System.out.println(Arrays.toString(arr));
-
sort:定制排序
根据o1-o2或o2-o1决定正序和倒序,实现定制排序
Integer[] arr = {7, -5, 28, 34, 10, -51, 62}; Arrays.sort(arr, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { // return o1 - o2; // 正序 return o2 - o1; // 倒序 } }); System.out.println(Arrays.toString(arr));
可以根据o1-o2或o2-o1决定正序和倒序,是因为在sort方法底层,会通过匿名内部类调用Comparator的compare方法,并根据compare方法的返回值决定排序的顺序
下面是一个帮助理解sort底层调用compare方法的例子
public class ArraysSortCustom { public static void main(String[] args) { int[] arr = {7, -5, 28, 34, 10, -51, 62}; sort(arr, new Comparator() { @Override public int compare(Object o1, Object o2) { int p1 = (Integer)(o1); int p2 = (Integer)(o2); // return p1 - p2; // 正序 return p2 - p1; // 倒序 } }); System.out.println(Arrays.toString(arr)); } // 冒泡排序 + 定制 public static void sort(int arr[], Comparator c){ int temp; for (int i = 0; i < arr.length - 1; i++) { for (int j = 0; j < arr.length - i - 1; j++) { if (c.compare(arr[j], arr[j + 1]) > 0){ temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } }
-
binarySearch:通过二分搜索进行查找,要求必须排好序
int[] arr = {7, -5, 28, 34, 10, -51, 62}; Arrays.sort(arr); System.out.println(Arrays.toString(arr)); // [-51, -5, 7, 10, 28, 34, 62] // binarySearch 二分查找 查找有序数组中的某个元素位置 //如果找到关键字,则返回值为关键字在排序后的数组中的位置索引,且索引从0开始。 int a = Arrays.binarySearch(arr, 28); System.out.println(a); // 4
-
copyOf:数组元素的复制
// copyOf 在原数组中,拷贝 n 个元素到新数组中 // 第二个参数小于0抛出异常 NegativeArraySizeException // 参数大于原数组长度,自动补充n int[] arr = {7, -5, 28, 34, 10, -51, 62}; // 拷贝arr到newArr int[] newArr = Arrays.copyOf(arr, arr.length); // int[] newArr = Arrays.copyOf(arr,-1); // NegativeArraySizeException System.out.println(Arrays.toString(newArr));
-
fill:数组元素填充
// fill 使用 n 替换数组中所有的元素 int[] arr = {7, -5, 28, 34, 10, -51, 62}; Arrays.fill(arr, 88); System.out.println(Arrays.toString(arr)); // [88, 88, 88, 88, 88, 88, 88]
-
equals:比较两个数组元素是否完全一致
int[] arr1 = {7, -5, 28, 34, 10, -51, 62}; int[] arr2 = {7, -5, 28, 34, 10, -51, 62}; System.out.println(Arrays.equals(arr1, arr2));
-
asList:将一组值转换成list
// asList 将一组数转成List集合 // ints 的运行类型是Arrays$ArrayList,是Arrays的一个静态内部类 // 如果传数组,不能是基本数据类型数组 List ints = Arrays.asList(2, 5, 6, 4); System.out.println(ints); // [2, 5, 6, 4] Integer[] intArr = {1, 2, 3}; List<Integer> integers = Arrays.asList(intArr); System.out.println(integers); // [1, 2, 3]
11.7 System
常用方法:
-
exit 退出当前程序
System.out,printil("hello"); System.exit(0);//参数是int型 System.out,printil("tom");//不会输出
-
arraycopy 复制数组元素,比较适合底层调用,一般使用Array.copyOf完成复制数组
// arraycopy 拷贝数组 // 参数列表:原数组,原数组起始位置,新数组,新数组起始位置,复制长度 int[] arr = {1, 2, 3}; int[] newArr = new int[3]; System.arraycopy(arr, 0, newArr, 0, arr.length); System.out.println(Arrays.toString(newArr)); // [1, 2, 3]
-
currentTimeMilens 返回当前时间距离1970-1-1的毫秒数
-
gc 运行垃圾回收机制 Sytem.gc()
11.8 BigInteger类和BigDecimal类
BigInteger类和BigDecimal类都是用于保存大数的,BigInteger类用于保存大整数,BigDecimal用于保存高精度浮点数
常用方法:
// 创建两个大数,下面方法例子中使用
BigInteger bigInteger = new BigInteger("12128498888888888888888888888884545");//在new时参数加上""
BigInteger bigInteger1 = new BigInteger("5555");
-
add 加
bigInteger = bigInteger.add(bigInteger1);
-
subtract 减
// subtract 减 BigInteger subtract = bigInteger.subtract(bigInteger1); System.out.println(subtract);
-
multiply 乘
// multiply 乘 BigInteger multiply = bigInteger.multiply(bigInteger1); System.out.println(multiply);
-
divide 除
// divide 除 BigInteger divide = bigInteger.divide(bigInteger1); System.out.println(divide);// 浮点数的除法有可能除不尽,这时会抛出异常ArithmeticException // 再加一个参数BigDecimal.ROUND_CEILING解决(过时,还能用) //新的,加参数RoundingMode.CEILING BigDecimal bigDecimal = new BigDecimal("121.28498888888888888888888888884545"); BigDecimal bigDecimal1 = new BigDecimal("5.555"); BigDecimal divide = bigDecimal.divide(bigDecimal1, BigDecimal.ROUND_CEILING);//旧 System.out.println(divide); BigDecimal divide = bigDecimal.divide(bigDecimal1, RoundingMode.CEILING);//新 System.out.println(divide);
11.9 Date类
Date类是第一代日期类,JDK 1.0就包含了Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用了,指的是java.util.Date。
Date类通常和SimpleDateFormat类配合使用,Date获取到的时间可以再自定义显示格式,通过SimpleDateFormat的format方法格式化,已经格式化的数据,也可以通过SimpleDateFormat的parse方法再转为Date类型
-
创建Date对象
Date date = new Date();//获取当前系统时间 Date date1 = new Date(545445545);//获取指定毫秒数得到时间 System.out.println(date.getTime());//获取某个时间对应的毫秒数 System.out.println(date); // Sun Jun 27 21:02:38 CST 2021
-
格式化Date
Date date = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss"); String format = simpleDateFormat.format(date); System.out.println(format); // 2021年06月27日 09:14:04
-
格式化时间转回Date
String str = "2021年06月27日 09:10:14"; // 注意格式必须对应字符串 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss"); Date parse = simpleDateFormat.parse(str); System.out.println(parse); // Sun Jun 27 09:10:14 CST 2021
11.10 Calendar
Calendar类是第二代日期类,在JDK 1.1引入
Calendar类是一个抽象类,并且构造器是私有的,它通过getInstance方法获取实例
下面是Calendar类的使用
Calendar calendar = Calendar.getInstance();
System.out.println("年:" + calendar.get(Calendar.YEAR));
System.out.println("月:" + (calendar.get(Calendar.MONTH) + 1));
System.out.println("日:" + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("时:" + calendar.get(Calendar.HOUR));
System.out.println("分:" + calendar.get(Calendar.MINUTE));
System.out.println("秒;" + calendar.get(Calendar.SECOND));
System.out.println("时:" + calendar.get(Calendar.HOUR_OF_DAY)); // 二十四小时进制
Calendar也存在很多问题
- 可变性:像日期和时间这样的类应该是不可变的
- 偏移性:Date中的年份是从1900开始的,而月份都从0开始
- 格式化:格式化只对Date有用,Calendar则不行
- 此外,它不是线程安全的;不能处理闰秒等
11.11 LocalDate类、LocalTime类和LocalDateTime类
LocalDate类、LocalTime类和LocalDateTime类是第三代日期类,jdk8加入的
LocalDate只包含日期,可以获取日期字段
LocalTime只包含时间,可以获取时间字段
LocalDateTime包含时间+日期,可以获取日期和时间字段
三种类获取字段的方法名一样
// LocalDateTime 包含年月日、时分秒
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
System.out.println("年:" + now.getYear());
System.out.println("月:" + now.getMonth());
System.out.println("月:" + now.getMonthValue());
System.out.println("日:" + now.getDayOfMonth());
System.out.println("时:" + now.getHour());
System.out.println("分:" + now.getMinute());
System.out.println("秒:" + now.getSecond());
// LocalDate 只包含年月日
LocalDate now1 = LocalDate.now();
System.out.println(now1);
// LocalTime 只包含时分秒
LocalTime now2 = LocalTime.now();
System.out.println(now2);
第三代日期类使用DateTimeFormatter类格式化,DateTimeFormatter和SimpleDateFormat用法类似
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh-mm-ss");
String format = dateTimeFormatter.format(now);
System.out.println(format);
-
plus:加时间
// plus 加时间 LocalDateTime now = LocalDateTime.now(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh-mm-ss"); LocalDateTime localDateTime = now.plusDays(956); System.out.println("956天后是:" + dateTimeFormatter.format(localDateTime));
-
minus:减时间
// minus 减时间 LocalDateTime now = LocalDateTime.now(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh-mm-ss"); LocalDateTime localDateTime1 = now.minusMinutes(5632); System.out.println("5632分钟前是:" + dateTimeFormatter.format(localDateTime1));
11.12 Instant
时间戳,Instant类似Date,可以和Date相互转换
-
Instant 转 Date
Instant instant = Instane.now(); Date date = Date.form(instant);
-
Date 转 Instant
Instant in = date.toInstant()