6.java常用类
6.1 String类
public class Main {
/*
1.概述
1.1 String:字符串,使用一对""引起来表示
1.2 String是声明为final的,不可被继承
1.3 String实现了Serializable接口:表示字符串是支持序列化的
实现了Comparable接口:表示String可以比较大小
1.4 String内部定义了final char[] value用于存储字符串数据(JDK9 之后是 final byte[] value)
1.4.1 final决定了value这个引用地址不可变,但是value数组元素仍然是可变的
1.4.2 String是不可变的关键都在底层的实现,而不是final char[] value中的final
2.String的不可变性
2.1 字符串常量池中是不会存储相同内容的字符串的
2.2 当对字符串重新赋值时,需要重写指定内存区域赋值,不能对原有的value进行赋值
2.3 当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能对原有的value进行赋值
2.4 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能对原有的value进行赋值
因为value是数组,数组一旦初始化就不能改变长度
*/
@Test
public void test1(){
String s1="abc";
String s2="abc";
System.out.println(s1==s2);//true
s1="hello";
System.out.println(s1);//hello
System.out.println(s2);//abc
String s3="abc";
String s4=s3.replace('a','m');
System.out.println(s3);//abc
System.out.println(s4);//mbc
String s5="abc";
s5+="def";
System.out.println(s5);//abcdef
}
/*
2.5 内存解析
*/
/*
3.String实例化的不同方式
3.1 方式说明
3.1.1 方式一:通过字面量定义的方式
3.1.2 方式二:通过new + 构造器的方式
3.2 两种方式创建的对象的不同
3.2.1 通过字面量定义的方式:在内存中创建了一个对象:value在常量池中对应的数据
3.2.2 通过new + 构造器的方式:在内存中创建了两个个对象:一个是堆中new的结构,另一个是value在常量池中对应的数据
3.3 两种方式保存的地址值的不同
3.3.1 通过字面量定义的方式:此时的s1和s2保存的地址值是在常量池中所开辟空间对应的地址值
3.3.2 通过new + 构造器的方式:此时的s3和s4保存的地址值是在堆中所开辟空间对应的地址值
*/
@Test
public void test2(){
//此时的s1和s2保存的地址值是在常量池中所开辟空间对应的地址值
String s1 = "javaEE";
String s2 = "javaEE";
//此时的s3和s4保存的地址值是在堆中所开辟空间对应的地址值
String s3=new String("javaEE");
String s4=new String("javaEE");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
}
/*
3.4 内存解析
*/
@Test
public void test3(){
Person p1 = new Person("Tom", 18);
Person p2 = new Person("Tom", 18);
System.out.println(p1.name==p2.name);//true
p1.name="Jerry";
System.out.println(p2.name);//Tom
System.out.println(p1.name==p2.name);//false
}
}
class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
/*
4.一道面试题
*/
public class Main {
String str=new String("good");
char[] ch={'t','e','s','t'};
public void change(String str,char ch[]){
str="test ok";
ch[0]='b';
}
public static void main(String[] args) {
Main main = new Main();
main.change(main.str,main.ch);
System.out.println(main.str);//good
System.out.println(main.ch);//best
}
}
public class Main {
/*
5.字符串拼接方式的对比
5.1 说明:
5.1.1 常量与常量拼接,返回在常量池中所开辟空间对应的地址值
5.1.2 只要其中一个是变量,返回在堆中所开辟空间对应的地址值
5.1.3 如果拼接的结果调用intern()方法,返回在常量池中所开辟空间对应的地址值
5.2 代码举例
*/
@Test
public void test1(){
String s1 = "javaEE";
String s2 = "hadoop";
String s3 = "javaEEhadoop";
String s4 = "javaEE" + "hadoop";
String s5 = s1 + "hadoop";
String s6 = "javaEE" + s2;
String s7 = s1 + s2;
System.out.println(s3 == s4);//true,因为常量池中不会存在相同内容的常量
System.out.println(s3 == s5);//false
System.out.println(s3 == s6);//false
System.out.println(s3 == s7);//false
System.out.println(s5 == s6);//false
System.out.println(s5 == s7);//false
System.out.println(s6 == s7);//false
final String s8 = "javaEE";//s4:常量
String s9 = s8 + "hadoop";
System.out.println(s3 == s9);//true
String s10 = s6.intern();//返回在常量池中数据"javaEEhadoop"对应的地址值
System.out.println(s3 == s10);//true
}
}
/*
6.常用方法
*/
public class Main {
/*
6.1 int length():返回字符串的长度: return value.length
6.2 char charAt(int index): 返回某索引处的字符:return value[index]
6.3 boolean isEmpty():判断是否是空字符串:return value.length == 0
6.4 String toLowerCase():使用默认语言环境,将 String 中的所有字符转换为小写
6.5 String toUpperCase():使用默认语言环境,将 String 中的所有字符转换为大写
6.6 String trim():返回字符串的副本,忽略前导空白和尾部空白
6.7 boolean equals(Object obj):比较字符串的内容是否相同
6.8 boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写
6.9 String concat(String str):将指定字符串连接到此字符串的结尾。 等价于用“+”
6.10 int compareTo(String anotherString):比较两个字符串的大小
6.11 String substring(int beginIndex):返回一个新的字符串,它是此字符串从beginIndex开始截取到最后的一个子字符串。
6.12 String substring(int beginIndex, int endIndex) :返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串
*/
@Test
public void test1(){
String s1="HelloWorld";
System.out.println(s1.length());//10
System.out.println(s1.charAt(0));//H
System.out.println(s1.charAt(9));//d
System.out.println(s1.isEmpty());//false
String s2=s1.toLowerCase();
System.out.println(s2);//helloworld
String s3=s1.toUpperCase();
System.out.println(s3);//HELLOWORLD
String s4=" He llo World ";
String s5=s4.trim();
System.out.println(s5);//He llo World
String s6="HelloWorld";
String s7="helloworld";
System.out.println(s6.equals(s7));//false
System.out.println(s6.equalsIgnoreCase(s7));//true
String s8="abc";
String s9=s8.concat("def");
System.out.println(s9);//abcdef
String s10="abc";
String s11=new String("abd");
System.out.println(s10.compareTo(s11));//-1,因为c-d=-1
String s12="北京尚硅谷教育";
String s13=s12.substring(2);//尚硅谷教育
String s14=s12.substring(2,5);//尚硅谷
System.out.println(s13);
System.out.println(s14);
}
/*
6.13 boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
6.14 boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
6.15 boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始
6.16 boolean contains(CharSequence s):当且仅当此字符串包含指定的 char 值序列时,返回 true
6.17 int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
6.18 int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始搜索
6.19 int lastIndexOf(String str):返回指定子字符串在此字符串中最后一次出现处的索引
6.20 int lastIndexOf(String str, int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索
注:indexOf和lastIndexOf方法如果未找到都是返回-1
*/
@Test
public void test2(){
String s1="helloworldhelloworld";
System.out.println(s1.endsWith("ld"));//true
System.out.println(s1.startsWith("he"));//true
System.out.println(s1.startsWith("wo", 5));//true
System.out.println(s1.contains("hello"));//true
System.out.println(s1.indexOf("lo"));//3
System.out.println(s1.indexOf("lol"));//-1
System.out.println(s1.indexOf("lo", 4));//13
System.out.println(s1.lastIndexOf("lo"));//13
System.out.println(s1.lastIndexOf("lo",12));//3
//什么情况下,indexOf(s)和lastIndexOf(s)返回值相同?
//情况1:存在唯一的一个s。情况二:不存在s
}
/*
替换:
6.21 String replace(char oldChar, char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的
6.22 String replace(CharSequence target, CharSequence replacement):使用给定的 replacement 替换此字符串中出现的所有 target
6.23 String replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串
6.24 String replaceFirst(String regex, String replacement):使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串
匹配:
6.25 boolean matches(String regex):告知此字符串是否匹配给定的正则表达式。
切片:
6.26 String[] split(String regex):根据给定正则表达式拆分此字符串。
6.27 String[] split(String regex, int limit):根据给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中
*/
@Test
public void test3(){
String s1="北京尚硅谷教育北京";
String s2=s1.replace('北','东');
System.out.println(s1);//北京尚硅谷教育北京
System.out.println(s2);//东京尚硅谷教育东京
String s3=s1.replace("北京","上海");
System.out.println(s3);//上海尚硅谷教育上海
String s4="12hello34world5java7891mysql1456";
String s5 = s4.replaceAll("\\d+", ",");
System.out.println(s5);//,hello,world,java,mysql,
String s6 = s4.replaceFirst("\\d+", ",");
System.out.println(s6);//,hello34world5java7891mysql1456
String s7 = s5.replaceAll("^,|,$", "");
System.out.println(s7);//hello,world,java,mysql
String s8="12345";
//判断s8字符串中是否全部由数字组成,即由1-n个数字组成
boolean matches1 = s8.matches("\\d+");
System.out.println(matches1);//true
String tel="0571-4534269";
//判断这是否是一个杭州电话,由0571-后接7到8位数字构成
boolean matches2 = tel.matches("0571-\\d{7,8}");
System.out.println(matches2);//true
String s9="hello|world|java";
String[] split1 = s9.split("\\|");
for(int i=0;i<split1.length;i++){
System.out.println(split1[i]);
}
/*输出
hello
world
java
*/
String[] split2 = s9.split("\\|", 2);
for(int i=0;i<split2.length;i++){
System.out.println(split2[i]);
}
/*输出
hello
world|java
*/
}
}
public class Main {
/*
7.String与其它结构的转换
7.1 与基本数据类型、包装类之间的转换(详见包装类处)
7.2 与字符数组之间的转换
7.2.1 String --> char[]:调用String的toCharArray()
7.2.2 char[] --> String:调用String的构造器
*/
@Test
public void test1(){
String s1="abc123";
char[] chars = s1.toCharArray();
for(int i=0;i<chars.length;i++){
System.out.println(chars[i]);
}
char[] arr=new char[]{'h','e','l','l','o'};
String s = new String(arr);
System.out.println(s);//hello
}
/*
7.3 与字节数组之间的转换
7.3.1 编码(看得懂 ---> 看不懂的二进制数据):String --> byte[]:调用String的getBytes()
7.3.2 解码(看不懂的二进制数据 ---> 看得懂):byte[] --> String:调用String的构造器
7.3.3 说明:要求解码方式必须与编码方式一致,否则会出现乱码
*/
@Test
public void test2() throws UnsupportedEncodingException {
String s1="abc123中国";
byte[] bytes = s1.getBytes();//使用默认的编码方式进行编码
System.out.println(Arrays.toString(bytes));
byte[] gbks = s1.getBytes("gbk");//使用"gbk"编码方式进行编码
System.out.println(Arrays.toString(gbks));
String s2 = new String(bytes);//使用默认的解码方式进行解码
System.out.println(s2);
String s3 = new String(gbks);//使用默认的解码方式进行解码,出现乱码。原因:解码方式与编码方式不一致!
System.out.println(s3);
String s4 = new String(gbks, "gbk");
System.out.println(s4);//使用"gbk"解码方式进行解码,没有出现乱码。原因:解码方式与编码方式一致!
}
/*
7.4 与StringBuffer、StringBuilder之间的转换
7.4.1 String -->StringBuffer、StringBuilder:调用StringBuffer、StringBuilder构造器
7.4.2 StringBuffer、StringBuilder -->String:
7.4.2.1 调用String构造器
7.4.2.2 StringBuffer、StringBuilder的toString()
*/
@Test
public void test3(){
String string = new String("abc");
StringBuffer stringBuffer = new StringBuffer(string);
StringBuilder stringBuilder = new StringBuilder(string);
StringBuffer stringBuffer1 = new StringBuffer("bcd");
StringBuilder stringBuilder1 = new StringBuilder("bcd");
String string1 = new String(stringBuffer1);
String string2 = stringBuffer1.toString();
String string3 = new String(stringBuilder1);
String string4 = stringBuilder1.toString();
}
}
6.2 StringBuffer与StringBuilder类
public class Main {
/*
1.String、StringBuffer、StringBuilder三者的对比
1.1 String:不可变的字符序列;底层使用final char[] value存储
1.2 StringBuffer:可变的字符序列;线程安全的,效率低;底层使用char[] value存储
1.3 StringBuilder:可变的字符序列;jdk5.0新增的,线程不安全的,效率高;底层使用char[] value存储
*/
@Test
public void test1(){
StringBuffer s1 = new StringBuffer("abc");
s1.setCharAt(0,'m');
System.out.println(s1);//mbc
s1.append(1);
System.out.println(s1);//mbc1
}
/*
2.StringBuffer与StringBuilder的内存解析
2.1 以StringBuffer为例,StringBuilder与StringBuffer底层存储并无区别
*/
@Test
public void test2(){
String s = new String();//char[] value = new char[0];
String abc = new String("abc");//char[] value = new char[]{'a','b','c'};
StringBuffer stringBuffer1 = new StringBuffer();//char[] value = new char[16];底层创建了一个长度是16的数组
System.out.println(stringBuffer1.length());//0,value.length=16;
stringBuffer1.append('a');//value[0] = 'a';
stringBuffer1.append('b');//value[1] = 'b';
StringBuffer stringBuffer2 = new StringBuffer("abc");//char[] value = new char["abc".length() + 16];
System.out.println(stringBuffer2.length());//3
}
/*
2.2 扩容问题:如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组
默认情况下,扩容为原来容量的2倍 + 2,同时将原数组中的元素复制到新的数组中
2.3 指导意义:开发中建议大家使用:StringBuffer(int capacity) 或 StringBuilder(int capacity)
3.对比String、StringBuffer、StringBuilder三者的执行效率
从高到低:StringBuilder > StringBuffer > String
*/
@Test
public void test3(){
long startTime=0L;
long endTime=0L;
String text="";
StringBuffer stringBuffer = new StringBuffer("");
StringBuilder stringBuilder = new StringBuilder("");
startTime=System.currentTimeMillis();
for(int i=0;i<200000;i++){
text=text+i;
}
endTime=System.currentTimeMillis();
System.out.println("String的执行时间:"+(endTime-startTime));
startTime=System.currentTimeMillis();
for(int i=0;i<200000;i++){
stringBuilder.append(i);
}
endTime=System.currentTimeMillis();
System.out.println("StringBuffer的执行时间:"+(endTime-startTime));
startTime=System.currentTimeMillis();
for(int i=0;i<200000;i++){
stringBuilder.append(i);
}
endTime=System.currentTimeMillis();
System.out.println("StringBuilder:"+(endTime-startTime));
/*输出
String的执行时间:9675
StringBuffer的执行时间:6
StringBuilder:5
*/
}
/*
4.StringBuffer和StringBuilder的常用方法
以StringBuffer为例,StringBuilder与StringBuffer的常用方法除了是否线程安全,其他并无区别
4.1 StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
4.2 StringBuffer delete(int start,int end):删除指定位置的内容
4.3 StringBuffer replace(int start,int end,String str):把[start,end)位置替换为str
4.4 StringBuffer insert(int offset,xxx):在指定位置插入xxx
4.5 StringBuffer reverse():把当前字符序列逆转
4.6 int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
4.7 String substring(int start,int end):返回一个新字符串,它是此字符串从start开始截取到end(不包含)的一个子字符串
4.8 int length():返回字符串中实际元素的个数:return count 其中count不是value.length
4.9 char charAt(int n):返回某索引处的字符:return value[index]
4.10 void setCharAt(int n,char ch):将字符串指定索引处的字符置为给定字符:value[n]=ch
总结:
增:append(xxx)
删:delete(int start,int end)
改:setCharAt(int n ,char ch) / replace(int start, int end, String str)
查:charAt(int n)
插:insert(int offset, xxx)
长度:length();
遍历:for() + charAt() / toString()
*/
@Test
public void test(){
StringBuffer stringBuffer = new StringBuffer("abc");
stringBuffer.append(1);
stringBuffer.append('1');
System.out.println(stringBuffer);//abc11
stringBuffer.delete(2,4);
System.out.println(stringBuffer);//ab1
stringBuffer.replace(2,3,"hello");
System.out.println(stringBuffer);//abhello
stringBuffer.insert(2,false);
System.out.println(stringBuffer);//abfalsehello
stringBuffer.reverse();
System.out.println(stringBuffer);//olleheslafba
int he = stringBuffer.indexOf("he");
System.out.println(he);//4
System.out.println(stringBuffer.length());//12
String substring = stringBuffer.substring(0, 3);
System.out.println(substring);//oll
System.out.println(stringBuffer.charAt(0));//o
stringBuffer.setCharAt(0,'a');
System.out.println(stringBuffer);//alleheslafba
}
}
6.3 JDK8之前的日期API
public class Main {
/*
1.获取系统当前时间:System类中的 static long currentTimeMillis()
返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差,称为时间戳
*/
@Test
public void test1(){
long l = System.currentTimeMillis();
System.out.println(l);
}
/*
2.java.util.Date类与java.sql.Date类
2.1 体系结构
java.util.Date类
|---java.sql.Date类
2.2 java.util.Date类
2.2.1 两个构造器的使用
2.2.1.1 构造器一:Date():创建一个对应当前时间的Date对象
2.2.1.2 构造器二:Date(long date):创建指定时间戳的Date对象
2.2.2 两个方法的使用
2.2.2.1 String toString():显示当前Date对象对应的年、月、日、时、分、秒
2.2.2.2 long getTime():获取当前Date对象对应的时间戳
*/
@Test
public void test2(){
//构造器一:创建一个对应当前时间的Date对象
Date date1 = new Date();
System.out.println(date1);//输出Thu Jan 19 13:46:48 CST 2023
System.out.println(date1.getTime());//1674107208441
//构造器二:创建指定毫秒数的Date对象
Date date2 = new Date(1674106940748L);
}
/*
2.3 java.sql.Date类(对应着数据库中的日期类型的变量)
2.3.1 一个构造器的使用
2.3.1.1 Date(long date):创建指定时间戳的Date对象
2.3.2 两个方法的使用
2.3.2.1 String toString():显示当前Date对象对应的年、月、日
2.3.2.2 long getTime():获取当前Date对象对应的时间戳
*/
@Test
public void test3(){
java.sql.Date date = new java.sql.Date(1674106940748L);
System.out.println(date);//2023-01-19
System.out.println(date.getTime());//1674106940748
/*
2.3.3 将java.util.Date对象转换为java.sql.Date对象
*/
Date date1 = new Date();
java.sql.Date date2 = new java.sql.Date(date1.getTime());
}
/*
3.java.text.SimpleDataFormat类
3.1 SimpleDateFormat对日期Date类的格式化和解析
3.1.1 SimpleDateFormat的实例化:new + 构造器(SimpleDateFormat提供了一系列构造器)
3.1.2 两个操作:
3.1.2.1 格式化:日期 --->字符串:String format(Date date)
3.1.2.2 解析:字符串 ---> 日期:Date parse(String source)
*/
@Test
public void test4() throws ParseException {
//实例化SimpleDateFormat
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat();
//默认方式格式化:按默认格式格式化
Date date = new Date();
System.out.println(date);//Thu Jan 19 14:27:18 CST 2023
String format1 = simpleDateFormat1.format(date);
System.out.println(format1);//2023/1/19 下午2:25
//默认方式解析:要求字符串必须是符合SimpleDateFormat默认识别的格式
String str="2023/1/19 下午2:25";
Date parse1 = simpleDateFormat1.parse(str);
System.out.println(parse1);//Thu Jan 19 14:27:18 CST 2023
//按指定方式格式化和解析:调用带参的构造器
//格式化:按构造器参数格式格式化
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String format2 = simpleDateFormat2.format(date);
System.out.println(format2);//2023-01-19 02:33:41
//解析:要求字符串必须是符合SimpleDateFormat识别的格式(通过构造器参数体现),否则,抛异常
Date parse2 = simpleDateFormat2.parse("2023-01-19 14:33:50");
System.out.println(parse2);//Thu Jan 19 14:33:50 CST 2023
}
/*
4.练习
4.1 练习一:字符串"2023-01-19"转换为java.sql.Date
*/
@Test
public void test5() throws ParseException {
String birth="2023-01-19";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date parse = simpleDateFormat.parse(birth);
System.out.println(parse);//Thu Jan 19 00:00:00 CST 2023
java.sql.Date date = new java.sql.Date(parse.getTime());
System.out.println(date);//2023-01-19
}
/*
5.Calendar类:日历类、抽象类
5.1 实例化
5.1.1 方式一:创建其子类GregorianCalendar的对象
5.1.2 方式二:调用其静态方法getInstance()
*/
@Test
public void test6(){
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getClass());//class java.util.GregorianCalendar
/*
5.2 常用方法
*/
//5.2.1 int get(int field):获取相关属性
int day = calendar.get(Calendar.DAY_OF_MONTH);//19
System.out.println(day);
System.out.println(calendar.get(Calendar.DAY_OF_YEAR));//19
//5.2.2 void set(int field, int value):设置相关属性
calendar.set(Calendar.DAY_OF_MONTH,22);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//22
//5.2.3 void add(int field, int amount):加减相关属性
calendar.add(Calendar.DAY_OF_MONTH,3);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//25
calendar.add(Calendar.DAY_OF_MONTH,-3);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//22
//5.2.4 Date getTime():日历类-->Date
Date date1= calendar.getTime();
System.out.println(date1);//Sun Jan 22 15:40:59 CST 2023
//5.2.5 void setTime(Date date):Date-->日历类
Date date2 = new Date();
calendar.setTime(date2);
day= calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(day);//19
}
}
6.4 JDK8之后的日期API
public class Main {
/*
1.日期时间API的迭代:
1.1 第一代:jdk 1.0 Date类
1.2 第二代:jdk 1.1 Calendar类,一定程度上替换Date类
1.3 第三代:jdk 1.8 提出了新的一套API
2.前两代存在的问题举例:
2.1 可变性:像日期和时间这样的类应该是不可变的。
2.2 偏移性:Date中的年份是从1900开始的,而月份都从0开始。
2.3 格式化:格式化只对Date有用,Calendar则不行。
2.4 此外,它们也不是线程安全的;不能处理闰秒等。
3.java 8 中新的日期时间API涉及到的包
*/
/*
4.时间点:Instant
4.1 说明:
4.1.1 时间线上的一个瞬时点。
4.1.2 类似于 java.util.Date类
4.2 实例化:
4.2.1 方式一:static Instant now():获取本初子午线的标准时间
4.2.2 方式二:static Instant ofEpochMilli(long epochMilli):通过给定的时间戳,获取Instant实例
*/
@Test
public void test2(){
Instant instant = Instant.now();
System.out.println(instant);//2023-01-19T09:33:24.109674200Z
Instant instant1 = Instant.ofEpochMilli(1674121118192L);
System.out.println(instant1);//2023-01-19T09:38:38.192Z
/*
4.3 常用方法
*/
//4.3.1 OffsetDateTime atOffset(ZoneOffset offset):添加时间的偏移量
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime);//本初子午线+8小时(北京时间):2023-01-19T17:35:34.963199900+08:00
//4.3.2 long toEpochMilli():获取时间戳
long l = instant.toEpochMilli();
System.out.println(l);//1674121118192
}
/*
5.本地日期、本地时间、本地日期时间的使用:LocalDate / LocalTime / LocalDateTime
5.1 说明:
5.1.1 分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息
5.1.2 LocalDateTime相较于LocalDate、LocalTime,使用频率更高
5.1.3 类似于Calendar
5.2 实例化:
5.2.1 方式一:static LocalXxx now():获取当前的日期、时间、日期+时间
5.2.2 方式二:static LocalXxx of(Xxx):设定指定的年、月、日、时、分、秒。没有偏移量
*/
@Test
public void test1(){
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDate);//2023-01-19
System.out.println(localTime);//16:32:09.587090700
System.out.println(localDateTime);//2023-01-19T16:32:09.587090700
LocalDateTime of = LocalDateTime.of(2023, 1, 19, 16, 3, 50);
System.out.println(of);//2023-01-19T16:03:50
/*
5.3 常用方法
*/
//5.3.1 Xxx getXxx():获取相关属性
System.out.println(localDateTime.getDayOfMonth());//19
System.out.println(localDateTime.getDayOfWeek());//THURSDAY
System.out.println(localDateTime.getDayOfYear());//19
System.out.println(localDateTime.getMonthValue());//1
System.out.println(localDateTime.getMinute());//32
//体现不可变性
//5.3.2 LocalXxx withXxx(Xxx):设置相关属性
LocalDate localDate1 = localDate.withDayOfMonth(22);
System.out.println(localDate);//2023-01-19
System.out.println(localDate1);//2023-01-22
LocalDateTime localDateTime1 = localDateTime.withHour(4);
System.out.println(localDateTime);//2023-01-19T16:40:59.210670500
System.out.println(localDateTime1);//2023-01-19T04:40:59.210670500
//5.3.3 LocalXxx plusXxx(Xxx)和minusXxx(Xxx):加减相关属性
LocalDateTime localDateTime2 = localDateTime.plusMonths(3);
System.out.println(localDateTime);//2023-01-19T16:45:52.049405700
System.out.println(localDateTime2);//2023-04-19T16:45:52.049405700
LocalDateTime localDateTime3 = localDateTime.minusDays(6);
System.out.println(localDateTime);//2023-01-19T16:45:52.049405700
System.out.println(localDateTime3);//2023-01-13T16:45:52.049405700
}
/*
6.日期时间格式化类:DateTimeFormatter
6.1 说明:
6.1.1 格式化或解析日期、时间
6.1.2 类似于SimpleDateFormat
6.2 常用方法:
6.2.1 实例化方式:DateTimeFormatter.格式
6.2.1.1 预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
6.2.1.2 本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.SHORT)
6.2.1.3 自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
6.2.2 两个操作:
6.2.2.1 格式化:日期 --->字符串:String format(TemporalAccessor temporal)
6.2.2.2 解析:字符串 ---> 日期:TemporalAccessor parse(CharSequence text)
*/
@Test
public void test3(){
//预定义的标准格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
//格式化:日期-->字符串
LocalDateTime localDateTime = LocalDateTime.now();
String format = formatter.format(localDateTime);
System.out.println(localDateTime);//2023-01-19T18:12:52.709950400
System.out.println(format);//2023-01-19T18:12:52.7099504
//解析:字符串-->日期
TemporalAccessor parse = formatter.parse("2023-01-19T18:12:52.7099504");
System.out.println(parse);//{},ISO resolved to 2023-01-19T18:12:52.709950400
//本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.SHORT)
//格式化:日期-->字符串
DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
String format1 = formatter1.format(localDateTime);
System.out.println(format1);//2023/1/19 下午6:21
DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
String format2 = formatter2.format(LocalDate.now());
System.out.println(format2);//2023年1月19日星期四
//解析:字符串-->日期
TemporalAccessor parse1 = formatter1.parse(format1);
System.out.println(parse1);//{},ISO resolved to 2023-01-19T18:25
TemporalAccessor parse2 = formatter2.parse(format2);
System.out.println(parse2);//{},ISO resolved to 2023-01-19
//自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
//格式化:日期-->字符串
String format3 = formatter3.format(localDateTime);
System.out.println(format3);//2023-01-19 06:31:07
//解析:字符串-->日期
TemporalAccessor parse3 = formatter3.parse("2023-01-19 06:31:07");
System.out.println(parse3);//{MilliOfSecond=0, HourOfAmPm=6, SecondOfMinute=7, MinuteOfHour=31, NanoOfSecond=0, MicroOfSecond=0},ISO resolved to 2023-01-19
}
}
6.5 Java比较器
public class Main {
/*
1.Java比较器的使用背景:
Java中的对象,正常情况下,只能进行 == 或 != 比较。不能进行 > 或 < 比较
但是在开发场景中,我们需要对多个对象进行排序,言外之意,就需要比较对象的大小。
如何实现?使用两个接口中的任何一个:Comparable 或 Comparator
2.自然排序:使用Comparable接口
2.1 说明:
2.1.1 像String、包装类等实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象大小的方式
2.1.2 像String、包装类重写compareTo()方法以后,使用sort()方法默认进行从小到大的排列
2.1.3 重写compareTo(obj)的规则:
2.1.3.1 如果当前对象this大于形参对象obj,则返回正整数
2.1.3.2 如果当前对象this小于形参对象obj,则返回负整数
2.1.3.3 如果当前对象this等于形参对象obj,则返回零
2.1.4 对于自定义类来说,如果需要排序,我们可以让自定义类实现Comparable接口,重写compareTo(obj)方法,在compareTo(obj)方法中指明如何排序
*/
@Test
public void test1(){
String[] strings=new String[]{"a","c","d","b"};
Arrays.sort(strings);
System.out.println(Arrays.toString(strings));
Integer[] integers=new Integer[]{3,2,1};
Arrays.sort(strings);
System.out.println(Arrays.toString(integers));
Goods[] goods=new Goods[5];
goods[0]=new Goods("appleMouse",34);
goods[1]=new Goods("huaweiMouse",20);
goods[2]=new Goods("leiseMouse",40);
goods[3]=new Goods("luojiMOuse",56);
goods[4]=new Goods("zuoweiMouse",56);
Arrays.sort(goods);
System.out.println(Arrays.toString(goods));
}
/*
3.定制排序:使用Comparator接口
3.1 使用场景:当元素的类型没实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口,但排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序
3.2 重写compare(Object o1,Object o2)的规则:
如果o1大于o2,则返回正整数
如果o1小于o2,则返回负整数
如果o1等于o2,则返回零
*/
@Test
public void test2(){
Goods[] goods=new Goods[5];
goods[0]=new Goods("appleMouse",34);
goods[1]=new Goods("huaweiMouse",20);
goods[2]=new Goods("leiseMouse",40);
goods[3]=new Goods("luojiMouse",50);
goods[4]=new Goods("luojiMouse",56);
Arrays.sort(goods, new Comparator() {
//按名称从低到高,再按照价格从高到低
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Goods&&o2 instanceof Goods){
Goods goods1=(Goods) o1;
Goods goods2=(Goods) o2;
if(goods1.getName().equals(goods2.getName())){
return -Double.compare(goods1.getPrice(),goods2.getPrice());
}else {
return goods1.getName().compareTo(goods2.getName());
}
}
throw new RuntimeException("输入的类型不一致");
}
});
System.out.println(Arrays.toString(goods));
}
/*
4.两种排序方式对比
4.1 使用Comparable接口能保证Comparable接口实现类的对象在任何位置都可以比较大小
4.2 使用Comparator接口属于临时性的比较
*/
}
class Goods implements Comparable{
private String name;
private double price;
public void setName(String name) {
this.name = name;
}
public void setPrice(double price) {
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public Goods(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public int compareTo(Object o) {
//按照价格从低到高,再按照名称从高到低
if(o instanceof Goods){
//方式一:
Goods goods=(Goods) o;
if(this.price> goods.price){
return 1;
}else if (this.price< goods.price){
return -1;
}else {
return -this.name.compareTo(goods.name);
}
//方式二:
// return Double.compare(this.price,goods.price);
}
throw new RuntimeException("传入的数据类型不一致!");
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
6.6 其他类
public class Main {
/*
1.System类
1.1 System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包
1.2 由于该类的构造器是private的,所以无法创建该类的对象。其内部的成员变量和成员方法都是static的,所以也可以很方便的进行调用
1.3 方法:
static long currentTimeMillis():返回时间戳
static void exit(int status):该方法的作用是退出程序。其中status的值为0代表正常退出,非零代表异常退出
static void gc():该方法的作用是请求系统进行垃圾回收。至于系统是否立刻回收,则取决于系统中垃圾回收算法的实现以及系统执行时的情况
static String getProperty(String key):该方法的作用是获得系统中属性名为key的属性对应的值。系统中常见的属性名以及属性的作用如下表所示:
*/
@Test
public void test1(){
String javaVersion = System.getProperty("java.version");
System.out.println("java的version:" + javaVersion);
String javaHome = System.getProperty("java.home");
System.out.println("java的home:" + javaHome);
String osName = System.getProperty("os.name");
System.out.println("os的name:" + osName);
String osVersion = System.getProperty("os.version");
System.out.println("os的version:" + osVersion);
String userName = System.getProperty("user.name");
System.out.println("user的name:" + userName);
String userHome = System.getProperty("user.home");
System.out.println("user的home:" + userHome);
String userDir = System.getProperty("user.dir");
System.out.println("user的dir:" + userDir);
}
/*
2.Math类
2.1 java.lang.Math提供了一系列静态方法用于科学计算。其方法的参数和返回值类型一般为double型
2.2 方法:
abs 绝对值
acos,asin,atan,cos,sin,tan 三角函数
sqrt 平方根
pow(double a,double b) a的b次幂
log 自然对数
exp e为底指数
max(double a,double b)
min(double a,double b)
random() 返回0.0到1.0的随机数
long round(double a) double型数据a转换为long型(四舍五入)
toDegrees(double angrad) 弧度—>角度
toRadians(double angdeg) 角度—>弧度
3.BigInteger类、BigDecimal类
3.1 说明:
3.1.1 BigInteger类和BigDecimal类都是在java.math包下
3.1.1 BigInteger类:BigInteger可以表示不可变的任意精度的整数
3.1.2 java.math.BigDecimal类:要求数字精度比较高时用到
*/
@Test
public void test2(){
BigInteger bi = new BigInteger("12433241123");
BigDecimal bd = new BigDecimal("12435.351");
BigDecimal bd2 = new BigDecimal("11");
System.out.println(bi);//12433241123
// System.out.println(bd.divide(bd2));未指定结果处理方式,报错
System.out.println(bd.divide(bd2, BigDecimal.ROUND_HALF_UP));//默认保留3位小数,四舍五入:1130.486
System.out.println(bd.divide(bd2, 15, BigDecimal.ROUND_HALF_UP));//保留15位小数,四舍五入:1130.486454545454545
}
}