包装类

  • 针对八种基本数据类型相应的引用类型 —— 包装类


  • 包装类和基本数据的转换:

(1) jdk5之前采用手动装箱和拆箱的方式
(2) jdk5及以后采用自动装箱和拆箱的方式
(3)自动装箱底层调用的是valueOf方法
【装箱:基本数据类型 -> 包装类; 拆箱: 包装类 -> 基本数据类型】

手动装箱:

int n = 100;
Integer integer = new Integer(n);
Integer integer1 = Integer.valueOf(n);

手动拆箱:

int n2 = integer.intValue();

自动装箱:

//底层是用Integer.valueOf(parameter)实现的
Integer integer2 = n;

自动拆箱

//底层采用 parameter.intValue();
int n3 = integer2;

三元运算符是一个整体,精度要看整体的最高精度

  • 包装类与String转换: 【以Integer为例】
Integer i = 100;
//利用toString()方法完成Integer转换成String
String s1 = i.toString();
String s2 = String.valueOf(i);
String s3 = i + "";
//String转化为Integer
String str = "123";
Integer i1 = Integer.paraseInt(str);
Integer i2 = new Integer(str);
  • Integer经典面试题:
//示例一
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2);
//示例二
Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4);
//示例三
Integer i5 = 127;
Integer i6 = 127;
System.out.println(i5 == i6);
//示例四
Integer i7 = 128;
Integer i8 = 128;
System.out.println(i7 == i8);
//示例五
Integer i9 = 127;
Integer i10 = new Integer(127);
System.out.println(i9 == i10);
//示例六
Integer i11 = new Integer(127);
int i12 = 127;
System.out.println(i11 == i12);
//示例七
Integer i13 = 128;
int i14 = 128;
System.out.println(i13 == i14);

输出结果如下:

对产生的结果分析:

  • 通过new来创建新的整型包装类的对象,所以在利用==比较时肯定返回false 【所以示例一、二、五都为 false
  • 示例三、四都是采用的自动装箱,底层是通过Integer.valueOf()方法实现的,通过Ctrl+B快捷键查看源码
    public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);}

当参数大于IntegerCache.low,小于IntegerCache.high时,是直接在缓冲数组中取的值;当不在这个范围时才会创建一个新Integer对象
进一步查询源码可知:IntegerCache.low为-128, IntegerCache.high为127
所以示例三中,参数127在范围内,所以两个对象的地址相同,返回true;
示例四中,参数128不在范围内,所以两个对象的地址不同,返回false。

  • 只要有基本数据类型参与==比较,判断的就是 值是否相同【所以示例六、七返回true】

String类

  • String对象用于保存字符串,也就是一组字符序列
  • 字符串常量对象是用双引号括起来的字符序列。
  • 字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节

一、String类常用构造器

String s1 = new String();
String s2 = new String(parameter);
String s3 = new String(char [] ch);
String s4 = new String(char [] c, int startIndex, int count);
  • String类实现了Serializable接口 和 Comparable接口,可以在网络传输,也可以相互比较
  • String 是final类,不能被继承,而且初始化之后就不能改变 【字符可以修改,地址不能修改】

可以修改字符的内容,例如:s = "you";,此时s对应的地址仍然是0x123,只是内容发生了变化

  • String 有属性 private final char value[] 用于存储字符

二、String对象的创建方式

String s1 = "study";
String s2 = new String("study");

(1)通过构造器创建的对象:现在堆中创建空间,里面维护了value属性,指向常量池的空间,如果常量池有该字符串,则通过value直接指向,否则在常量池中重新创建,最终指向堆中的空间地址

(2)通过直接赋值的对象:先从常量池中查看是否有该字符串的数据空间,如果有直接指向;如果没有则重新创建,然后指向。最终指向的是常量池的空间地址

堆中存放的是引用对象的地址,如果问对象的属性,那么是在常量池中的地址。

Person p = new Person();
p.name = "赵先生";

此时这个对象p指向的是在堆中引用对象的地址,而p.name是在方法区的常量池中的地址
对于intern()方法,其作用是获取字符串对象在常量池中的地址

String s1 = "zbc";
String s2 = new String("zbc");
System.out.println(s1 == s2);
System.out.println(s1 == s2.intern());

s1对象直接赋值获得的,s2 对象是通过构造器获得的。所以s1的地址是该字符串在常量池中的地址,s2的地址是该引用对象在堆中的地址。
所以输出的第一个结果为 false
s2.intern() 返回的是s2在常量池中的地址,因为s2s1的字符串内容相同,所以在常量池中的地址也相同。
所以输出的第二个结果为 true

三、String类的特性分析

(1) final 无论是String类、还是其中保存数据的 value[ ] 都是final类型的
众所周知, final定义的变量有成为常量,在初始化之后就不能修改

String str = "sunny";
str = "day";

这样是没有问题的,但是不是将原来字符串的内容修改了呢?

起初,在堆的常量池中,创建了sunny,并将引用对象指向这个地址;之后在常量池中检测是否存在day,如果不存在就创建这个字符串,然后将引用对象指向这个新的地址,存在就直接指向这个地址即可。
所以说,并不是修改了原来的字符串,而是创建了一个新的对象

(2) String类的字符串拼接
第一种,几个字符串常量拼接

String s1 = "hello" + "world";

这种只会创建一个对象,在常量池中保存 helloworld字符串,s1指向这个地址

第二种,几个字符串对象拼接

String str1 = "hello";
String str2 = "world";
String str3 = str1 + str2;

这种情况与第一种方式不同,因为 str1 和 str2是已经存在的字符串对象,它的实际创建过程是这样的:
先会创建一个StringBuffer类的对象,然后调用两次 append()方法,将这两个字符串拼接到一起,最后调用 toString()方法,将StringBuffer类的对象转化为String类的对象,返回给str3。

所以str3在内存中,实际是在堆中创建了一块空间,指向常量池的 helloworld,最后将堆中value[ ]的地址赋给 str3

(3) 创建对象,调用方法,属性修改的内存分析

public class Main{String s = new String("powferful");final char [] ch = {z, a, p, p, i, n, e, s, s};public void change(String s, char [] ch){s = "badly";ch[0] = 'h';}public static void main (String [] args){Main life = new Main();life.change(life.s, life.ch);System.out.println(life.s + " and " + life.ch);}
}

程序从主方法开始,创建对象是在堆中创建的,对象有两个属性,数组的空间也是在堆中分配的

当调用一个方法时,就会生成一个栈,此时执行change方法,在栈中生成了一个change的方法栈,其中对象s是通过直接赋值获得的,所以在常量池中创建对象badly,然后返回给 s;数组ch直接指向堆中的地址,并修改了它的第一个字符

当方法调用结束,该空间被释放,此时执行打印输出,调用的 s 和 ch仍然是主方法栈中的。
所以输出, powerful and happiness

四、String类的常用方法

(1) String类是用于保存字符串常量的,每次更新都需要重新开辟空间,效率较低。

String str1 = "perfect";
String str2 = "Perfect";
//区分大小写比较
System.out.println(str1.equals(str2));
//不区分大小写比较
System.out.println(str1.equalsIgnoreCase(str2));
//从前向后寻找
System.out.println(str1.indexOf(e));
//从后向前寻找
System.out.println(str1.lastIndexOf(e));
//获取字符串长度
System.out.println(str1.length());
//截取指定索引后的全部字符串
System.out.println(str1.substring(3));
//从指定索引开始截取指定范围的字符串 【此时为索引0-2】
System.out.println(str1.substring(0, 3));
方法名 作用
equals 比较字符串内容是否相同
equalsIgnoreCase 不区分大小写比较内容是否相同
length 获取字符串长度
indexOf 返回字符串中第一次出现该字符的索引
lastIndexOf 返回字符串中最后一次出现该字符的索引
substring 根据指定索引截取字符串


(2) String类提供的第二组常用方法

package com.zwh.java.string_;/*** @author Bonbons* @version 1.0*/
public class String01 {public static void main(String[] args) {/*//第一组方法String str1 = "perfect";String str2 = "Perfect";//区分大小写比较System.out.println(str1.equals(str2));//不区分大小写比较System.out.println(str1.equalsIgnoreCase(str2));//从前向后寻找System.out.println(str1.indexOf('e'));//从后向前寻找System.out.println(str1.lastIndexOf('e'));//获取字符串长度System.out.println(str1.length());//截取指定索引后的全部字符串System.out.println(str1.substring(3));//从指定索引开始截取指定个数的字符串System.out.println(str1.substring(0, 3));
*///第二组方法String str3 = "Lucky";//转成大写System.out.println(str3.toUpperCase());//转成小写System.out.println(str3.toLowerCase());//拼接System.out.println(str3.concat(" day"));//替换System.out.println(str3.replace("Luck", "Suit"));//分割String poem = "两只黄鹂鸣翠柳,一行白鹭上青天";String [] p = poem.split(",");for(String s : p){System.out.println(s);}//转化为字符数组System.out.println(str3.toCharArray()[0]);//比较字符串大小,前者大返回正数,后者大返回负数,相等返回零//如果两个字符串,一个为其中另一个的前部分,那么返回的为两个字符串长度之差(前面-后面)String person1 = "jack";String person2 = "john";System.out.println(person1.compareTo(person2)); //一个不同字符的差值//格式化填充字符串String name = "小明";String sex = "男";int age = 18;double score = 88.888;//%.2f 会保留小数点后两位,而且还会进行四舍五入处理String strFormat = "我叫 %s, 性别 %s,今年 %d 岁, 期末成绩为 %.2f。";System.out.println(String.format(strFormat, name, sex, age, score));}
}
方法名 作用
toUpperCase 将字符串中字母转化为大写
toLowerCase 将字符串中字母转化为小写
concat 拼接字符串
replace 将字符串中指定元素替换成新元素
split 根据指定字符进行分割,返回一个字符串数组
toCharArray 将字符串转化为字符数组
compareTo 比较字符串大小
format 由占位符组成的字符串,后面跟要填充的字符串


StringBuffer类

  • StringBuffer代表可变字符序列,可对字符串内容进行增删属于一个容器,很多方法与String类相同
  • StringBuffer保存的是字符串变量,可以更改里面的内容,不用每次都更新地址【只有在value[]内存不够时,才会开辟新空间,把原来的内容拷贝过去,然后更新地址】

一、StringBuffer结构分析

(1)StringBuffer类是final类型的,不能被继承

(2)该类继承了AbstractStringBuilder,实际该类就是通过父类的 char [] value来存储字符串的

(3)该类实现了Serializable接口,该类的对象可以串行化

(4)StringBuffer字符内容是存储在 char [] value中,所以进行增加或删除操作时,不用每次都更换地址【创建新的对象】

(5) StringBuffer的常用构造器

  • 默认创建一个大小为16的字符数组
StringBuffer sb = new StringBuffer();

  • 根据传入的正整型参数,创建指定大小的字符串数组
StringBuffer sb = new StringBuffer(30);

  • 根据传入的字符串,创建一个字符串长度+16的字符串数组
StringBuffer sb = new StringBuffer("night");

二、StringBuffer的转换

  • String类转化为StringBuffer
//利用构造器
String s = "good";
StringBuffer sb1 = new StringBuffer(s);
//利用拼接
StringBuffer sb2 = new StringBuffer();
sb2.append(s);
  • StringBuffer类转化为String
//利用StringBuffer类提供的toString方法
String s1 = sb1.toString();
//利用构造器
String s2 = new String(sb2);

三、StringBuffer的常用方法

方法名 作用
append(String s) 添加字符串s(拼接)
delete(int start, int end) 删除索引 start <= index < end 处的字符串
replace(int start, int end, String s) 将[start,end)范围的字符串替换为字符串s
indexOf(String s) 查找指定子串s在字符串中第一次出现的位置
lastIndexOf(String s) 查找指定子串s在字符串中最后一次出现的位置
insert(int index, String s) 在索引index位置插入字符串s
length() 获取字符串的长度

四、StringBuffer的应用

(1) 利用StringBuffer构造器创建的对象和利用 append() 方法创建的对象有什么区别?

String s = null;
StringBuffer sb = new StringBuffer();
sb.append(s);
System.out.println(sb.length());
System.out.println(sb);
  • 利用 append() 方法

当传入的字符串对象为空时,append() 方法会判断是否为空串

如果为空,那么就会调用AbstractStringBuffer类的 appendNull() 方法

从该方法中,我们可以看出实际是添加了一个 null 的字符串
之后正常输出,sb字符串的长度为4,输出内容 null

  • 利用构造器
String s = null;
StringBuffer sb = new StringBuffer(s);

会产生空指针异常报错

在调用该构造器时,会获取字符串的长度,因为传入的为null,所以此处str也为空

(2) 将从键盘获得的价格的整数部分每三位添加一个逗号【hhh,说实话有点像算法题】

public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String price = scanner.next();StringBuffer sb = new StringBuffer(price);//遍历寻找插入点for(int i = sb.lastIndexOf(".") - 3; i > 0; i -= 3){//插入","sb.insert(i, ",");}System.out.println(sb);}
}


StringBuilder

  • StringBuilder 不是线程安全的,一般用于单线程的情况下,这种情况下比StringBuffer要快

  • StringBuilder类提供与StringBuffer类兼容的API,主要操作为appendinsert,可重载这些方法以接收任何类型的数据

  • StringBuilder类与StringBuffer类相同,继承了AbstractStringBuilder类,利用父类的字符数组存储可变的字符序列

  • StringBuilder类是final的,不允许被继承,实现了Serializable接口,其对象是可以串行化的【对象可以网络传输,可以保存到文件】

  • StringBuilder的方法没有synchronized关键字【没有做互斥处理】,因此在单线程的情况下使用

  • StringStringBufferStringBuilder三者的比较:

(1)String 不可变字符序列,效率低,重复率高
(2)StringBuffer 可变字符序列,效率高,线程安全
(3)StringBuilder 可变字符序列,效率最高,线程不安全


Math

  • Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
方法名 作用
abs 求绝对值
pow(a, b) 求幂运算
ceil 向上取整
floor 向下取整
round 四舍五入
sqrt 求开方
random 求随机数
max 最大值
min 最小值
  • 应用案例:
public class MathTest01 {public static void main(String[] args) {//求绝对值int num1 = -5;System.out.println("求-5的绝对值:" + Math.abs(num1));//求幂System.out.println("求2的3次幂:" + Math.pow(2,3));//向上取整double num2 = 3.54;System.out.println(num2 + "向上取整:" + Math.ceil(num2));//向下取整System.out.println(num2 + "向下取整:" + Math.floor(num2));//四舍五入System.out.println(num2 + "四舍五入的结果为:" + Math.round(num2));//求开方System.out.println("4开平方:" + Math.sqrt(4));//随机数System.out.println("生成1-10的随机数:" + Math.random()* 10);//最大值System.out.println(num1 + " and " + num2 + " 的最大值:" + Math.max(num1, num2));//最小值System.out.println(num1 + " and " + num2 + " 的最小值:" + Math.min(num1, num2));}
}


Arrays

一、常用方法:

方法名 作用
toString() 返回数组的字符串形式
sort 将数组排序【正序或逆序】
binarySearch 可查找有序数组中的元素索引
copyOf 拷贝指定数组中指定个数的元素
fill 为数组填充相同的指定元素
equals 判断两个数组的元素是否完全相同
asList 将数组转化为集合【不能进行集合的操作】

(1) toString() 方法

public class ArraysTest {public static void main(String[] args) {//toString()方法,将数组转为字符串输出int [] num = {2, 5, 8, 0};System.out.println(Arrays.toString(num));}
}


实现原理:

    public static String toString(Object[] a) {if (a == null)return "null";int iMax = a.length - 1;if (iMax == -1)return "[]";StringBuilder b = new StringBuilder();b.append('[');for (int i = 0; ; i++) {b.append(String.valueOf(a[i]));if (i == iMax)return b.append(']').toString();b.append(", ");}}

对于数组类型,还可以为任意其他基础数据类型,若采用那些类型的数组,取值时用 a[i]即可。

  • 简述数组为空和长度为零的区别?
int [] arr = null;
int [] arr = new int[0];

当数组不为空时,才能去判断长度。
对于数组长度定义为零只是一种定义,对于存储本身没有意义,但是可以作为一些辅助作用。
(2) sort() 方法

public class ArraysTest {public static void main(String[] args) {int [] num = {2, 5, 8, 0};//sort()方法,将数组排序,最常见的是从小到大的排序Arrays.sort(num);System.out.println(Arrays.toString(num));}
}


数组是引用类型,排序操作会直接影响原数组

实现逆序排序

public class ArraysTest {public static void main(String[] args) {//此处使用的包装类Integer[] num = {2, 5, 8, 0};Arrays.sort(num, new Comparator() {//利用匿名内部类来实现接口@Overridepublic int compare(Object o1, Object o2) {Integer i1 = (Integer) o1;Integer i2 = (Integer) o2;return i2 - i1;}});System.out.println(Arrays.toString(num));}
}


实现原理:
1)Arrays.sort(arr, new Comparator())
2)最终到TimSort类的 binarySort方法
3)执行下面的代码,会根据动态绑定机制 c.compare()执行我们输入的匿名内部类

while(left < right){int mid = (left + right) >>> 1;if(c.compare(pivot, a[mid]) < 0)right = mid;elseleft = mid + 1;
}
4)new Comparator(){public int compare(Object o1, Object o2) {Integer i1 = (Integer) o1;Integer i2 = (Integer) o2;return i2 - i1;}
}

5)接口返回的值正负会决定是正序还是逆序

(3) binarySearch() 方法

class Main{public static void main(String [] args){int num = {0, 1, 2, 3, 4, 5, 8};int index = Arrays.binarySearch(num, 3);System.out.println("3的索引为:" + index);}
}


当数组中不存在目标值时,返回的值为该目标值应该在数组中的位置加一取反

return -(low + 1);

假设目标值为6,那么如果存在该数组中的索引为6,索引方法返回 -7。

(4)copyOf() 方法

int [] n1 = {2, 1, 0};
int [] n2 = Arrays.copyOf(n1, 2);
System.out.println(Arrays.toString(n2));


如果拷贝个数小于零,那么就会报错
如果拷贝个数大于原数组的大小,那么其余位置会补空 【null】

(5) fill() 方法

int [] num = new int[3];
Arrays.fill(num,6);
System.out.println(Arrays.toString(num));


为指定数组填充指定的元素,也可以覆盖掉原来的数组元素
(6) equals() 方法

int [] n1 = {1, 2, 3};
int [] n2 = {1, 2, 3};
System.out.println(Arrays.equals(n1, n2));


比较方法中的两个数组的元素是否完全相同,如果相同返回true,如果存在不同则返回false

(7) asList() 方法

int [] num = {1, 2, 3};
List list = Arrays.asList(num);

会根据传入的数组返回一个List类型的集合,编译类型为List接口,运行类型是这个接口中的一个内部类 ArrayList

二、应用案例

  • 通过这个应用案例可以更好的理解上面 sort() 方法的逆序实现原理
  • 采用 冒泡 + binarySort 结合的方式实现的
  • 代码部分:
import java.util.Arrays;
import java.util.Comparator;/*** @author Bonbons* @version 1.0*/
public class ArraysSortCustom {public static void main(String[] args) {//初始化一个待排序的数组int [] num = {0, 3, 1, 5, 2, 8, 4};//调用排序方法bubbleSort(num, new Comparator(){@Overridepublic int compare(Object o1, Object o2) {//强转为整型数据后,采用自动拆箱转化为int类型int i1 = (Integer)o1;int i2 = (Integer)o2;return i1 - i2;}});//打印数组System.out.println("排序后的数组为:" + Arrays.toString(num));}//创建一个冒泡+binarySort的方法public static void bubbleSort(int [] arr, Comparator c){//总共需要比较arr.length - 1 趟,每趟确定一个元素的位置for (int i = 0; i < arr.length - 1; i++) {//比较相邻两个元素的大小for (int j = 0; j < arr.length - 1; j++) {//此时是正序排序if(c.compare(arr[j], arr[j + 1]) > 0){int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}
}


(2)通过书的价格来对书进行排序,该类包含两个属性 名字和价格。

package com.zwh.java.math_;import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;/*** @author Bonbons* @version 1.0*/
public class ArraysTest {public static void main(String[] args) {Book [] books = new Book[4];books[0] =new Book("红楼梦",100);books[1] =new Book("金瓶梅",90);books[2] =new Book("青年文摘", 5);books[3] =new Book("java从入门到放弃w",30);//根据价格从小到大将书排序Arrays.sort(books, new Comparator<Book>() {@Overridepublic int compare(Book o1, Book o2) {double priceDiff = o1.getPrice() - o2.getPrice();//逆序更改此处的值即可if(priceDiff > 0)return 1;else if(priceDiff < 0)return -1;elsereturn 0;}});//输出Book类的信息System.out.println(Arrays.toString(books));}
}class Book{private String name;private int price;//构造器public Book(){}public Book(String name, int price) {this.name = name;this.price = price;}//Get和Set方法public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}public void setPrice(int price) {this.price = price;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", price=" + price +'}';}
}

System

方法名 作用
exit 退出当前程序
arraycopy 拷贝数组元素
currentTimeMillens 返回当前时间
gc 垃圾回收机制

(1)System.exit(int parameter)
通过启动关闭序列来终止当前正在运行的虚拟机。
状态参数为,代表正常退出;非零时代表异常终止。

(2)System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

int [] newArr = new int[8];int [] curArr = {1, 2, 3, 4};System.arraycopy(curArr, 0, newArr, 0, 4);System.out.println(Arrays.toString(newArr));

(3)System.currentTimeMillis()
返回当前时间与1970年1月1日凌晨之间的差值,一般以毫秒级为单位

//可以用来测试一个代码块的运行时间
long cur = System.currentTimeMillis();
int count = 0;
for(int i = 0; i < 10000000; i++){if(i % 2 == 0){count++;}}
long cur2 = System.currentTimeMillis();
System.out.println("运行该算法需要的时间为:" + (cur2 - cur) + "ms");


(4) System.gc()

  • System.gc() 是Java提供的垃圾回收机制,当它被调用时,它将尽最大努力从内存中清理垃圾(未被引用的对象)。
  • 当调用该方法时,将触发完整的GC事件。在GC完成之前,整个JVM正在运行的所有服务都会被暂停。

BigInteger 和 Decimal

一、BigInteger

  • 当我们要存储一个特别大的数时,可以使用BigInteger类【利用字符串传入数据】
  • 当我们要对该类型的数据进行加减乘除时,要使用对应的方法,不能直接进行 + - * /
  • 如果要对BigInteger类进行运算,参与运算的两个对象都必须为BigInteger类型
import java.math.BigInteger;
public class BDMethod {public static void main(String[] args) {//存储一个大数,用long存储会提示Integer number too largeBigInteger num = new BigInteger("8931741723712837");System.out.println(num);//对BigInteger类型的数据进行算术运算BigInteger num2 = new BigInteger("123");//加法采用add() 方法System.out.println(num.add(num2));//减法采用subtract()方法System.out.println(num.subtract(num2));//乘法采用multiply()方法System.out.println(num.multiply(num2));//除法采用divide()方法System.out.println(num.divide(num2));}
}

二、BigDecimal

  • 当我们需要保存一个精度很高的数时,我们可以采用BigDecimal类
  • 方法与BigInteger相同

add() 加法
subtract() 减法
multiply() 乘法
divide() 除法

在使用除法因为可能会出现除不尽的时候,就会抛出异常,我们可以采用

BigDecimal bd1 = new BigDecimal("1.231545623212315");
BigDecimal bd2 = new BigDecimal("9.3124124515");
System.out.println(bd1.divide(bd2, BigDecimal.ROUND_CEILING));

这样就会保留与分子相同的精度

Date

第一代日期类

一、 Date类的关系图


Date类为第一代日期类,可以精确到毫秒级,但是现在其中很多方法和构造器已经被弃用,部分开发仍然会使用该类

二、 Date类的时间格式

采用的是国外的时间格式

public class Date01 {public static void main(String[] args) {Date d1 = new Date();System.out.println(d1);}
}


所以我们需要进行格式化,利用SimpleDateFormat的对象来完成格式化

对于格式化时,字母的使用大小写是有区别的,可以参考上面的表格

SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
System.out.println(sdf.format(d1));

三、 Date类的其他用法

(1) 利用传入的毫秒数来设置时间 【不能超过长整型的范围】
当前Date类还保留一个 public Date(Long date)的构造器,通过传入的一个长整型的毫秒数来获取时间。

Date d2 = new Date(832490849);
System.out.println(sdf.format(d2));

如果为正数,那么为1970年1月1日以后的时间
如果为负数,那么为1970年1月1日之前的时间

(2) 利用指定的字符串来设置时间 【获得的时间仍为Date类的初始格式】
利用了SimpleDateFormat类的parse方法
待转化的字符串的格式,要与创建的SimpleDateFormat类的对象格式相同

String s = "2022年5月21日 00:00:00 星期六";
//在主方法处抛出异常
Date d3 = sdf.parse(s);
System.out.println(d3);
System.out.println(sdf.format(d3));


此处通过主方法抛出了异常,因为该方法是这样的parse(String text, ParsePosition pos)

text - A String ,其中一部分应解析。
pos - 具有 ParsePosition的索引和错误索引信息的 ParsePosition对象。

第二类日期类

一、Calendar类的关系图


Calendar类是一个抽象类,我们通常使用的是它的私有无参构造方法
通过提供的getInstance()来获得实例

二、Calendar类的应用

调用方法创建的该类对象,是将当前时间的所有信息都存储到该类的字段中

Calendar c = Calendar.getInstance();
System.out.println(c);


如果我们想直观的来查看时间,就要通过 get(字段) 方法从该对象中取出需要的字段信息

System.out.println(c.get(Calendar.YEAR)+"年"
+(c.get(Calendar.MONTH)+1)+"月"
+c.get(Calendar.DAY_OF_MONTH)+"日"
+c.get(Calendar.HOUR)+"时"
+c.get(Calendar.MINUTE)+"分"
+c.get(Calendar.SECOND)+"秒");


Calendar类没有提供对应的格式化类,所以需要自己来完成需要的时间字段拼接【时间的格式自由度变高】

注意:该类中有许多字段,例如这样:HOUR 、HOUR_OF_DAY
它们代表的含义是不同的,前者是12小时制,后者是24小时制
类似的字段还有很多,可以根据需要选取

第三代日期类

Calendar类自由度很高的情况下,也出现很多问题:

(1)可变性:日期与时间这样的类应该都是不可变的
(2)偏移性:月份是从0月开始
(3)格式化:格式化对Calendar类无法使用
(4)线程不安全,不能处理润秒的问题(每隔2天多出1s)

jdk8 之后,加入了第三代日期类
LocalDate 代表年月日
LocalTime 代表时分秒
LocalDateTime 代表年月日 时分秒

LocalDateTime为例

一、LocalDateTime的关系图


该类实现了很多接口,只有一个构造器

public LocalDateTime(LocalDate, LocalTime)

我们一般通过该类提供的now() 方法来利用当前时间返回LocalDateTime的对象

public class Main{public static void main(String[] args) {LocalDateTime dlt1 = LocalDateTime.now();System.out.println(dlt1);}
}

二、LocalDateTime的几个方法

该类提供了很多方法,此处选取几个为例,具体可以参考相关JDK的api

public class LocalDate01 {public static void main(String[] args) {LocalDateTime dlt1 = LocalDateTime.now();System.out.println(dlt1);//常见方法System.out.println("年 = " + dlt1.getYear());System.out.println("月 = " + dlt1.getMonthValue());System.out.println("日 = " + dlt1.getDayOfMonth());System.out.println("时 = " + dlt1.getHour());System.out.println("分 = " + dlt1.getMinute());System.out.println("秒 = " + dlt1.getSecond());}
}


对于月的获取有两个方法 getMonth() 与 getMonthValue(),前者返回的是字符串【英文月份】,后者显示的是数字【第几个月】

对当前日期进行算术运算(加、减

LocalDateTime ldt1 = LocalDateTime.now();DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 hh:mm:ss E");System.out.println("当前时间为: " + dtf.format(ldt1));System.out.println("十年之后的日子: " + dtf.format(ldt1.plusYears(10)));System.out.println("五个月前的日子: " + dtf.format(ldt1.minusMonths(5)));

三、LocalDateTime类的格式化

SimpleDateFormat类似,DateTimeFormatter为该类提供格式化

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 hh:mm:ss");
String s = dtf.format(dlt1);
System.out.println(s);

在创建DateTimeFormatter对象时,利用了该类的ofPattern()方法,使用指定的模式创建格式化程序。
在利用该对象调用format方法将LocalDateTime类型的时间格式化

四、LocalDateTime的时间戳

Instant时间戳与第一代时间Date类似,可以与其相互转换
利用静态方法now()获取当前时间戳的对象

Instant now = Instant.now();
System.out.println(now);

将时间戳对象转化为Date对象

Date date = Date.from(now);

将Date对象转化为时间戳对象

Instant instant = date.toInstant();

【重拾Java系列】—— 八大常用类相关推荐

  1. 安卓小菜鸟重拾Java系列002.Java转义字符与与sax解析xml

    已经好久没有更新博客了,炎热的夏天正如我的心情一样枯燥乏味,今年是互联的寒冬,作为一个菜鸟已经深深的感觉到了,因为自己失业了.从去年的年末的一些听闻,自己竟没有准备好迎接失业,以至于一年了,只比以前强 ...

  2. Java八大常用类小结

    Java的八大常用类 文章目录 Java的八大常用类 1.内部类 内部类的优点 2.Object类 3.包装类 4.数学类(Math类) 5.时间类 6.String类 7.String Builde ...

  3. 重拾Java Network Programming(一)IO流

    前言 最近在重拾Java网络编程,想要了解一些JAVA语言基本的实现,这里记录一下学习的过程. 阅读之前,你需要知道 网络节点(node):位于网络上的互相连通的设备,通常为计算机,也可以是打印机,网 ...

  4. Java学习之路3——方法定义、调用【重拾Java】

    Java学习之路3--方法定义.调用[重拾Java] 方法定义 为什么要写方法 方法完整的定义形式.调用 方法定义的格式 修饰符 返回值类型 返回值 调用格式 方法重载 方法定义 为什么要写方法 对于 ...

  5. 【JDK源码】java.lang包常用类详解

    接下来的几天开始JDK源码的学习和总结,之前看<java编程思想>的时候看到java的基础知识有很多,其中支撑着这些基础的基础中的基础当属JDK.JDK的基础代码里面又分了很多基础的模块, ...

  6. php byte stringbuffer,重拾java基础(十三):String姐妹StringBuffer、StringBuilder总结

    重拾java基础(十三):String姐妹StringBuffer.StringBuilder总结 一.StringBuffer类概述buffer:缓冲 2. 字符串缓冲区,跟String非常相似,都 ...

  7. Java学习之路1——安装JDK1.8||安装idea2022||Java项目创建【重拾Java】

    Java学习之路1--安装JDK1.8||安装idea2022[重拾Java] 前言 安装 安装JDK1.8 安装idea2022(JetBrains Toolbox) Java项目创建 创建 项目结 ...

  8. Java基础复习-常用类

    Java基础复习-常用类 本文仅对学习过程中所缺java知识点的查缺补漏复习 String 代表字符串.Java程序中的所有字符串字面值(如"abc")都作为此类的实例实现. St ...

  9. 《重学Java系列》之 注解基础

    不诗意的女程序媛不是好厨师~ 转载请注明出处,From李诗雨-[https://blog.csdn.net/cjm2484836553/article/details/104432728] <重 ...

最新文章

  1. 把毛选和鲁迅全集喂给AI后,写出来的高考作文太对味了
  2. Mongodb集群 - 副本集内部选举机制
  3. WaitForMultipleObjects用法详解,一看就懂
  4. “苹果光环”褪色后,瑞声靠什么坐稳头把交椅?
  5. vue 怎么在字符串中指定位置插入字符_vue项目中在可编辑div光标位置插入内容的实现代码...
  6. 为CentOS 6 配置本地YUM源
  7. 再不自动化就晚啦!优云教你4步打造基于CentOS的产品镜像
  8. typedef 字符串_typedef在C中使用字符数组(定义别名来声明字符串)的示例
  9. /frameworks/support
  10. 如何判断浏览器/标签是否有效[重复]
  11. 招聘 | 语言资源高精尖创新中心研发人员招聘启事
  12. 【FPGA】TestBench中关于@eachvec
  13. gsp计算机设施设备表格,GSP计算机系统内审表.doc
  14. selenium--自动化识别图片验证码并输入
  15. MAC OS读取NTFS格式硬盘
  16. 浅析统一操作系统UOS与深度Deepin区别
  17. 如何用手机保存APP上的视频
  18. C语言中lwr是谁的缩写,C语言中关于字符串的操作(转)
  19. 硬路由、软路由、主路由、旁路由对比分析
  20. 哈利波特与死圣中文版

热门文章

  1. 用 python-message 为程序库和日志模块解耦
  2. leetcode系列-62.不同路径
  3. MATLAB的imwrite函数显示没有权限写入问题
  4. 2022-1-9数据库原理试题
  5. 2021-12-1 set 、multiset 深度探索
  6. 途家与日本白马洽谈新合作 推介会分享民宿线上运营经验
  7. 俄罗斯方块的设计与实现
  8. win2003 玩魔兽争霸的方法.
  9. mc服务器切换模式显示英文字母,MC820高级设置说明.doc
  10. 2-2-2Webpack打包