包装类
Integer
【7】属性:
public class TestInteger {
public static void main(String[] args) {
//属性
System.out.println(Integer.MAX_VALUE);//2147483647
System.out.println(Integer.MIN_VALUE);//-2147483648
//物极必反 原理
System.out.println(Integer.MAX_VALUE+1);//-2147483648
System.out.println(Integer.MIN_VALUE-1);//2147483647
}
}
(2)String类型作为构造器参数
Integer i=new Integer("12");
Integer i1=new Integer("abc");//出现异常
包装类特有机制:自动装箱,自动拆箱
//自动装箱:int-----》Integer
Integer i=12;
System.out.println(i);
//自动拆箱:Integer----》int
Integer i3=new Integer(13);
int num=i3;
System.out.println(num);
(1)是从JDK1.5后新出的特性
(2)将基本数据类型和包装类进行快速的类型转换,实际上底层是通过调用valueOf方法进行转换的
常用方法
compareTo(),equals()
//Integer通过new关键字创建对象
Integer i1=new Integer("12");
Integer i2=new Integer("12");
System.out.println(i1.compareTo(i2));//(x < y) ? -1 : ((x == y) ? 0 : 1);
//compareTo
//只返回三个值:1,0,-1
System.out.println(i1==i2);//false
System.out.println(i1.equals(i2));//true
//equals
//Integer对Object中的equals方法进行了重写,比较的是底层封装的那个value的值
//Integer通过自动装箱创建对象
Integer i3=12;
Integer i4=12;
System.out.println(i3==i4);
//如果自动装箱的值在-128到127之间,那么比较的就是具体的数值,否则,比较的就是Integer对象的地址
int i=i3.intValue();
System.out.println(i);
System.out.println(Integer.parseInt("15"));
System.out.println(i3.toString());
System.out.println(Integer.valueOf("abc"));//出现异常,输入"123"对
System.out.println(Integer.valueOf("123",10));//返回10进制的数
valueOf()方法的底层
intValue()
将Integer转换为int类型
parseInt()
将字符串类型转换为int类型,这个字符串得是数字类型的字符串,否则会抛出异常
toString()
将Integer类型转换为String类型
日期相关类
java.util.Date
import java.util.Date;
public class TestDate {
public static void main(String[] args) {
//java.util.Date;
Date d=new Date();
System.out.println(d);
System.out.println(d.toGMTString());//过期方法,过时方法,废弃方法
System.out.println(d.toLocaleString());
System.out.println(d.getYear());//122,表示当前减去1900的时间
System.out.println(d.getMonth());//2,0表示1月,返回值在0-11之间
System.out.println(d.getTime());//1646200231913,距离1970-1.1 00.00.00的毫秒数
System.out.println(System.currentTimeMillis());//距离1970-1.1 00.00.00的毫秒数
/*(1)疑问:以后获取时间差用currentTimeMillis()还是getTime()
* 答案:currentTimeMillis()因为他是静态的,可以直接用类名调用,不需要创建对象
* (2)public static native long currentTimeMillis();
* 本地方法,为什么没有方法体?
* 因为这个方法的具体实现不是通过Java写的
* (3)这个方法的作用:
* 一般会去衡量一些算法所用的时间*/
long startTime=System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
System.out.println(i);
}
long endTime=System.currentTimeMillis();
System.out.println(endTime-startTime);
}
}
java.sql.Date
方法:valueOf()
import java.sql.Date;
public class TestSqlDate {
public static void main(String[] args) {
//java.sql.date
long l=1646200231913L;
Date d=new Date(l);//内部没有空构造器,只有带参的狗造器
System.out.println(d);
/*(1)java.sql.Date和java.util.Date区别:
* java.util.Date:年月日,时分秒
* java.sql.Date:年月日
* (2)java.sql.Date和java.util.Date联系:
* java.sql.Date (子类)extends java.util.Date(父类)*/
//java.sql.Date和java.util.Date相互转换
//util-----》sql
java.util.Date d1=new Date(l);
//java.util.Date d1=new java.util.Date(); //报错;方式1:向下转型
Date d2=(Date)d1;
/*报错原因:父类:Animal 子类:Dog
* Animal an=new Animal();
* Dog d=(Dog)an;这也不对,animal可能是猫或狗,直接强转不对
* 正确强转:
* Animal an=new Dog();
* Dog d=(Dog)an;*/
//方式2:利用构造器
Date d3=new Date(d1.getTime());
//sql-----》util
java.util.Date d4=d;//父类引用指向子类对象
//string----》sql.Date
Date d5=Date.valueOf("2022-03-02");
System.out.println(d5);
}
}
日期转换
String转换为java.util.date
public class Test01 {
public static void main(String[] args) {
//String转换为java.util.date
//string--->java.sql.date
java.sql.Date date=java.sql.Date.valueOf("2022-03-02");
//java.sql.date---->java.util.date
java.util.Date d=date;
System.out.println(d);
}
}
上述代码有局限性,字符串的格式只能是年-月-日拼接的形式,换成其他类型就会出现异常
parse()和format()
public class TestDF {
public static void main(String[] args) {
//日期转换
//public class SimpleDateFormat(子类) extends DateFormat(父类:抽象类)
//定义格式化标准:yyyy-MM-dd HH:mm:ss
DateFormat df=new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
//String--->date
try {
Date date=df.parse("2022.03.02 14:43:56");
System.out.println(date);
} catch (ParseException e) {
e.printStackTrace();
}
//date---->string
String d=df.format(new Date());//输出的是自定义格式
System.out.println(d);
}
}
Calendar()
方法:getInstance(),get(),set()
public class TestCalendar {
public static void main(String[] args) {
//Calendar是一个抽象类,不可以直接创建对象
//GregorianCalendar子类 extends Calendar父类:抽象类
Calendar cal=new GregorianCalendar();
Calendar cal1=Calendar.getInstance();
System.out.println(cal);
//常用的方法:get
System.out.println(cal.get(Calendar.YEAR));
System.out.println(cal.get(Calendar.MONTH));
System.out.println(cal.get(Calendar.DATE));
System.out.println(cal.get(Calendar.DAY_OF_WEEK));
System.out.println(cal.getActualMaximum(Calendar.DATE));//获取当月日期的最大天数
System.out.println(cal.getActualMinimum(Calendar.DATE));//获取当月日期的最小天数
//set:可以改变calendar中的内容
cal.set(Calendar.YEAR,1998);
cal.set(Calendar.MONTH,10);
cal.set(Calendar.DATE,13);
System.out.println(cal);
//string-----》calendar
//分解:string---》java,sql.date
java.sql.Date date=java.sql.Date.valueOf("2020-4-5");
//java.sql.date--->calendar
cal.setTime(date);
System.out.println(cal);
}
}
作业:打印日历
package homework;
import java.util.Calendar;
import java.util.Scanner;
/**
* @Auther:sky
* @Date:2022/3/2-03-02-15:18
* @Description:homework
* @Version:1.0
*/
public class RiLi {
public static void main(String[] args) {
//首先把string转成一个calendar类型
//录入日期的string
Scanner sc=new Scanner(System.in);
System.out.print("请输入你想要查看的日期:(提示:请按照例如2022-3-2的格式输入)");
String strDate=sc.next();
//转换类型
java.sql.Date date=java.sql.Date.valueOf(strDate);
Calendar cal=Calendar.getInstance();
cal.setTime(date);
//星期提示:
System.out.println("日\t一\t二\t三\t四\t五\t六\t");
//获取当前月份的天数
int maxDay=cal.getActualMaximum(Calendar.DATE);
//获取当前日期中的日
int nowDay=cal.get(Calendar.DATE);//通过对象和类名都可以访问,因为static
//将日期调整为本月1号
cal.set(Calendar.DATE,1);
//获取一号是这个月第几天
int num=cal.get(Calendar.DAY_OF_WEEK);
//相当于前面空出来的天数是num-1
int empty=num-1;
//在日期前将空格打印出来
for (int i = 1; i <=empty; i++) {
System.out.print("\t");
}
//引入一个计数器
int count=0;//计数器最开始值为0
count=count+empty;//前面的空格也要加上
//遍历:从一号到maxday
for (int i = 1; i <=maxDay ; i++) {
if(i==nowDay){//如果遍历的i和当前日子一样的话,多拼一个*
System.out.print(i+"*"+"\t");
}else{
System.out.print(i+"\t");
}
count++;//每在控制台输出一个数字,计数器做加一操作
if(count%7==0){//当计数器的个数是7的倍数时,就换行操作
System.out.println();
}
}
}
}
JDK新增的时间API
类:LocalDate / LocalTime / LocalDateTime
方法:now(),of(),get~() with~()
public class testxin {
public static void main(String[] args) {
//1.完成实例化
//方法1.now()--->获取当前的日期,时间,日期+时间
LocalDate ld = LocalDate.now();
LocalTime lt = LocalTime.now();
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ld);//2022-03-02
System.out.println(lt);//16:14:44.880
System.out.println(ldt);//2022-03-02T16:14:44.880
//方法2.of()--->设置指定的日期,时间,日期+时间
LocalDate lds= LocalDate.of(2010,5,6);
LocalTime lts = LocalTime.of(12, 35, 56);
LocalDateTime ldts=LocalDateTime.of(1890,12,23,13,24,15);
System.out.println(lds);//2010-05-06
System.out.println(lts);//12:35:56
System.out.println(ldts);//1890-12-23T13:24:15
//LocalDate,LocalTime 用的不如LocalDateTime多
//3.get*()方法
System.out.println(ldt.getYear());//2022
System.out.println(ldt.getMonth());//MARCH
System.out.println(ldt.getMonthValue());//3
System.out.println(ldt.getDayOfMonth());//2
System.out.println(ldt.getDayOfWeek());//WEDNESDAY
System.out.println(ldt.getHour());//16
System.out.println(ldt.getMinute());//28
System.out.println(ldt.getSecond());//20
//4.with*()方法,不叫set
//体会不可变性:即原来时间并没有被改变,而是在一个新的对象上进行操作
LocalDateTime ldt2 = ldt.withMonth(8);
System.out.println(ldt);//2022-03-02T16:35:23.726
System.out.println(ldt2);//2022-08-02T16:35:23.726
//提供了加减操作
LocalDateTime ldt3 = ldt.plusMonths(4);
System.out.println(ldt);//2022-03-02T16:35:23.726
System.out.println(ldt3);//2022-07-02T16:35:23.726
LocalDateTime ldt4 = ldt.minusMonths(4);
System.out.println(ldt4);//2021-11-02T16:35:23.726
}
}
LocalDate / LocalTime / LocalDateTime想要转换字符串
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.TemporalAccessor;
public class TestDTF {
public static void main(String[] args) {
//格式化类:DateTimeFormatter
//方式一:预定义的标准格式。如:ISO_LOCAL_DATE_TIME; ISO_LOCAL_DATE; ISO_LOCAL_TIME;
DateTimeFormatter df1 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
//df1可以帮我们完成LocalDateTime和string之间的相互转换
LocalDateTime ldt=LocalDateTime.now();
String str = df1.format(ldt);
System.out.println(str);//2022-03-02T16:57:52.615
//string---->LocalDateTime
TemporalAccessor parse = df1.parse("2022-03-02T16:57:52.615");
System.out.println(parse);//{},ISO resolved to 2022-03-02T16:57:52.615
//方式二:本地化相关的格式。如:oflocalizedDateTime()
//参数:FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT
//FormatStyle.LONG:2022年3月2日 下午05时04分45秒
//FormatStyle.MEDIUM:2022-3-2 17:05:39
//FormatStyle.SHORT:22-3-2 下午5:06
DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
//LocalDateTime---->string
LocalDateTime now = LocalDateTime.now();
String str2 = dtf.format(now);
System.out.println(str2);
//string---->LocalDateTime
TemporalAccessor parse1 = dtf.parse("22-3-2 下午5:06");//与上述long,medium,short格式对应
System.out.println(parse1);//{},ISO resolved to 2022-03-02T17:06
//方式三:自定义的格式。如:ofPattern("yyyy-MM-dd hh:mm:ss")----->重点,以后常用
DateTimeFormatter df3=DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
//LocalDateTime---->string
LocalDateTime now1=LocalDateTime.now();
String str3=df3.format(now1);
System.out.println(str3);//2022-03-02 07:01:35
//string---->LocalDateTime
TemporalAccessor parse2 = df3.parse("2022-03-02 07:01:35");
System.out.println(parse2);
//{MinuteOfHour=1, MilliOfSecond=0, HourOfAmPm=7, MicroOfSecond=0, SecondOfMinute=35, NanoOfSecond=0},ISO resolved to 2022-03-02
}
}
Math类
java.lang:直接使用,无需导包
final修饰类,这个类不能被继承
常用方法:(静态导入)
import static java.lang.Math.*;//静态导包后可以不写Math.,不建议使用
public class TestMath {
public static void main(String[] args) {
//常用属性:
System.out.println(Math.PI);
//常用方法:
System.out.println("随机数:"+Math.random());//[0.0, 1.0)
System.out.println("绝对值:"+Math.abs(-80));//80
System.out.println("向上取值:"+Math.ceil(9.1));//10.0
System.out.println("向下取值:"+Math.floor(9.9));//9.0
System.out.println("四舍五入:"+Math.round(3.4));//3
System.out.println("四舍五入:"+Math.round(3.5));//4
System.out.println("求最大值:"+Math.max(3,6));//6
System.out.println("求最小值:"+Math.min(3,6));//3
}
//静态导入时,如果与Math中方法重复了,那么会优先走本类中的方法
public static int random(){
return 100;
}
Random类
public class TestRandom {
public static void main(String[] args) {
//1.利用带参数的构造器创建对象
Random r=new Random(System.currentTimeMillis());
System.out.println(r.nextInt());
//2.利用空参构造器创造对象
Random r2=new Random();//表面在调用无参构造器,实际底层还是调用了带参构造器
System.out.println(r2.nextInt(10));//介于0(含)和指定值(不包括)均匀分布 int值
System.out.println(r2.nextDouble());//0.0(含)和 1.0(不包含)之间均匀分布的double值
}
}
String类
123不重要;底层是char类型数组
常用方法:
public class TestString {
public static void main(String[] args) {
//1.通过构造器来创建对象,底层就是给对象底层的value数组进行赋值操作
String str1=new String();
String str2=new String("abc");
String str3=new String(new char[]{'a','b','c'});
String str4="abc";
System.out.println(str4.length());//底层对应的数组的长度
System.out.println(str4.isEmpty());//底层判断的是char类型数组的长度是否为0
System.out.println(str4.charAt(1));//底层就是char数组下标对应的内容
String str5=new String("abc");
String str6=new String("abcd");
System.out.println(str5.equals(str6));//false
System.out.println(str5.compareTo(str6));//只有当完全相等才会输出0
String str7="abcdefhijk";
System.out.println(str7.substring(3));//defhijk
System.out.println(str7.substring(3,6));//def,包含3,不包含6
System.out.println(str7.concat("ppp"));//abcdefhijkppp
String str8="aabbc";
System.out.println(str8.replace('a','u'));//uubbc
String str9="a-b-c-d-e-f";
String[] strs=str9.split("-");
System.out.println(Arrays.toString(strs));//[a, b, c, d, e, f]
String str10="abc";
System.out.println(str10.toUpperCase());//ABC
String str11=" a b c ";
System.out.println(str11.trim());//a b c
System.out.println(String.valueOf(false));//false
}
}
equals(),对object类里的重写,判断值是否相等
compareTo():按字典顺序比较两个字符串
subString():对字符串进行截取
concat():对字符串进行合并,拼接
replace():对字符进行替换
split():按照指定的字符串,分裂成数组
toUpperCase():换成大写 toLowerCase():换成小写
trim():去除首尾空格
toString():调谁返回谁
转换为string类型:valueOf
String内存分析
2、new关键字创建对象
String s6=new String("abc");
内存:开辟两个空间(1.字符串常量池中的字符串 2.堆中开辟的空间)
3、有变量参与的字符串拼接
String a="abc";
String b=a+"def";
System.out.println(b);
a变量在编译的时候不知道a是”abc”字符串,所以不会进行编译期优化,不会直接合并为“abcdef”
StringBuilder类:可变字符串,StringBuffer
没有修饰符,同包下的子类也可以访问
底层精髓:内存扩容
public class TestStringBuilder {
psvm
//创建对象
StringBuilder s=new StringBuilder();
//表面上调用空构造器,实际底层是对value数组进行初始化,长度为16
StringBuilder s1=new StringBuilder(3);
//表面上调用有参构造器,传入一个int类型的数,实际底层是对value数组进行初始化,指定数组长度为传入的数
StringBuilder s2=new StringBuilder("abc");
//表面上调用有参构造器,传入一个String类型的数,实际底层是对value数组进行初始化,指定数组长度为字符串长度+16
s2.append("def").append("aaaaaaaa").append("bbb").append("oooooooo");//链式调用方式 return this
System.out.println(s2);
System.out.println(s2==s2.append("sky"));//true
}
3、内存分析
常用方法(StringBuilder和StringBuffer一样)
public class TestStringBuilder02 {
public static void main(String[] args) {
StringBuilder sb=new StringBuilder("nihaojavawodeshijie");
//增加
sb.append("我是sky");
System.out.println(sb);//nihaojavawodeshijie我是sky
//删除
sb.delete(2,5);
System.out.println(sb);//nijavawodeshijie我是sky,从0开始算,前包含后不包含
sb.deleteCharAt(2);
System.out.println(sb);//niavawodeshijie我是sky
//改---》插入
StringBuilder sb1=new StringBuilder("我是sky");
sb1.insert(2,",");//在下标为2的位置上插入
System.out.println(sb1);//我是,sky
//改---》替换
sb1.replace(2,3,":呀");//在下标[2,3)的位置上插入字符串
System.out.println(sb1);//我是:呀sky
sb1.setCharAt(3,'@');//只能改一位,加一位字符
System.out.println(sb1);//我是:@sky
//查找
StringBuilder sb2=new StringBuilder("这是yhm");
for (int i = 0; i <sb2.length(); i++) {
System.out.print(sb2.charAt(i)+"\t");//这 是 y h m
}
System.out.println();
//截取
String str=sb2.substring(2,5);//截取[2,5),返回的是一个新的string,对stringbuilder没有影响
System.out.println(str);//yhm
System.out.println(sb2);//这是yhm
}
}
public class TestStringBuilder02 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("nihaojavawodeshijie");
//增加
sb.append("我是sky");
System.out.println(sb);//nihaojavawodeshijie我是sky
//删除
sb.delete(2,5);
System.out.println(sb);//nijavawodeshijie我是sky,从0开始算,前包含后不包含
sb.deleteCharAt(2);
System.out.println(sb);//niavawodeshijie我是sky
//改---》插入
StringBuffer sb1=new StringBuffer("我是sky");
sb1.insert(2,",");//在下标为2的位置上插入
System.out.println(sb1);//我是,sky
//改---》替换
sb1.replace(2,3,":呀");//在下标[2,3)的位置上插入字符串
System.out.println(sb1);//我是:呀sky
sb1.setCharAt(3,'@');//只能改一位,加一位字符
System.out.println(sb1);//我是:@sky
//查找
StringBuffer sb2=new StringBuffer("这是yhm");
for (int i = 0; i <sb2.length(); i++) {
System.out.print(sb2.charAt(i)+"\t");//这 是 y h m
}
System.out.println();
//截取
String str=sb2.substring(2,5);//截取[2,5),返回的是一个新的string,对stringbuilder没有影响
System.out.println(str);//yhm
System.out.println(sb2);//这是yhm
}
}
理解可变与不可变的含义
不可变:在地址不变的情况下,改变值是不可能的
可变:在对象的地址不变的情况下,想把“abc”变成“def”是可能的,即上图中sb内的地址从未改变过
####面试题:String,StringBuilder,StringBuffer区别和联系