零、Java API
1.概念
Java应用程序编程接口(Java ApplicationProgramming Interface)
- 是运行库的集合
- 预先定义了一些接口和类
- 还特指API的说明文档,也称API帮助文档
2. Java常用包
一、Enum枚举
1.概念
- 类的对象只有 有限个,确定的
【当需要定义一组常量时,建议使用】 - 如果枚举类中只有一个对象,则可以作为单例模式的实现方式
2.语法
2.1 jdk5前,自定义枚举类
//自定义枚举类
public class Season{
//1.声明Season对象的属性:需要用private final修饰
private final String seasonName;
private final String seasonDesc;
//2.私有化类的构造器,并给对象属性赋值
private Season(String seasonName,String seasonDesc){
this.seasonName=seasonName;
this.seasonDesc=seasonDesc;
}
//3.提供当前枚举类的多个对象,public static final修饰的
public static final Season SPRING =new Season("春天","春");
public static final Season SUMMER =new Season("夏天","夏");
public static final Season AUTUMN=new Season("秋天","秋");
public static final Season WINTER=new Season("冬天","冬");
//4.获取枚举类对象的属性getter方法
//提供toString()方法
}
2.2 jdk5后,使用enum关键字定义枚举类
/*@Desc描述:定义jdk5的枚举类
* 定义的枚举类默认继承于java.lang.Enum类
* toString()方法不在打印地址值*/
public enum Season1 {
//1.提供当前枚举类的多个对象,多个对象之间用","隔开,末尾用";"结尾
SPRING, SUMMER,AUTUMN,WINTER;
//2.声明Season1对象的属性:需要用private final修饰
private final String seasonName;
private final String seasonDesc;
//3.私有化类的构造器,并给对象属性赋值
private Season1(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
//4.获取枚举类对象的属性getter方法
}
3. Enum常用方法
4.枚举类实现接口
4.1实现接口,并重写所有的抽象方法
public enum Answer2 implements Info1{
IS,NO;
@Override
public void show() {}
}
interface Info1{
void show();
}
4.2让枚举类的对象分别实现接口
public enum Answer implements Info{
IS{
@Override
public void show() {
System.out.println("对对对");
}
}, No {
@Override
public void show() {
System.out.println("错错错");
}
};
}
interface Info{
void show();
}
二、包装类
1.概念
- 将基本数据类型封装到一个类中,即将基本类型包装成一个类类型
2.作用
- 作为和基本数据类型对应的类型,方便对象的操作
- 操作每种基本数据类型的相关属性
3.包装类关系图
4.包装类和基本数据类型对应表
5.包装类构造方法
public Type (type value)
public Type (String value)
Type :表示包装类
type :表示基本数据类型
例:
//获取Integer类型的对象
Integer integer = new Integer(1);
Integer integer1 = new Integer("1");
System.out.println("创建对象的两个对象的是否相等:" + (integer == integer1));//创建对象的两个对象的是否相等false
//static Integer valueOf(int i)
Integer integer2 = Integer.valueOf(1);
Integer integer3 = Integer.valueOf("1");
System.out.println("使用valueOf的值是否相等:" + (integer2 == integer3));//使用valueOf的值是否相等:true
Integer integer4 = Integer.valueOf(127);
Integer integer5 = Integer.valueOf(127);
System.out.println("使用valueOf的127值是否相同:" + (integer4 == integer5));//使用valueOf的127值是否相同:true
/*
因为在实际开发中, -128~127之间的数据,用的比较多
如果每次都去创建对象,会浪费内存
所以,提前把这个范围之内的每一个数据都创建好对象
如果要用到不会创建新的,而是返回已经创建好的对象
*/
Integer integer6 = Integer.valueOf(128);
Integer integer7 = Integer.valueOf(128);
System.out.println("使用valueOf的128值是否相同:" + (integer6 == integer7));//使用valueOf的128值是否相同:false
//Boolean(String s)
Boolean bObj = new Boolean("true");//true
//不区别大小写
Boolean bObj2 = new Boolean("TRue");//true
//非true即为false
Boolean bObj3 = new Boolean("hello");//false
//Character(char value)
Character chobj2=new Character('男');
6.包装类和基本数据类型的转换
public type typeValue( );
tpye :表示基本数据类型
例 :
//定义布尔类型
boolean bl = true;
//使用构造方法实现基本数据类型向包装类转换
Boolean blObj = newBoolean(bl);
Integer itObj = newInteger(35);
Character chObj = newCharacter('男');
//包装类转换为基本数据类型
boolean b1=blObj.booleanValue();
int i=itObj.intValue();
char ch = chObj.charValue();
7. jdk5装箱拆箱
- 自动装箱Autoboxing
- 把基本类型变量直接转换为对应的包装类对象,或者转换为Object类型对象
- 自动拆箱AutoUnboxing
- 将包装类对象转换成对应的基本类型变量
//装箱,把基本类型变量直接转换为对应的包装类对象
Integer inObj= 5;
//装箱,或者转换为Object类型对象
Object boolObj= true;
System.out.println(inObj+","+boolObj);//5,true
//拆箱,将包装类对象转换成对应的基本类型变量
int it = inObj;
System.out.println(it);
if(boolObj instanceof Boolean) {
boolean b = (Boolean)boolObj;
System.out.println(b);
}
三、Math数学
1.概念
- 是一个帮助我们用于进行数学计算的工具类
- 私有化构造方法,所有的方法都是静态的
2. Math类常用方法
3.常用方法代码
/*@Desc描述: 使用Math数学类*/
public class TestMath {
public static void main(String[] args) {
/*
abs() : 获取绝对值
bug:
以int为例:取值范围 -2147483648 ~ 2147483647
如果没有正数与负数对应,那么传递负数结果有误
*/
System.out.println("-2147483647的绝对值: " + Math.abs(-2147483647));//-2147483647的绝对值: 2147483647
System.out.println("-2147483648的绝对值: " + Math.abs(-2147483648));//-2147483648的绝对值: -2147483648
/*
ceil() : 向上取整
进一法,往数轴的正方向进一
*/
System.out.println("13.14的向上取整: " + Math.ceil(13.14)); //13.14的向上取整: 14.0
System.out.println("-13.14的向上取整: " + Math.ceil(-13.14));//-13.14的向上取整: -13.0
/*
floor() :向下取整
往数轴的负方向进一
*/
System.out.println("13.14的向下取整: " + Math.floor(13.14));//13.14的向下取整: 13.0
System.out.println("-13.14的向下取整: " + Math.floor(-13.14));//-13.14的向下取整: -14.0
/*
round() :四舍五入
*/
System.out.println("12.1的四舍五入: " + Math.round(12.1));//12.1的四舍五入: 12
System.out.println("-12.6的四舍五入: " + Math.round(-12.6));//-12.6的四舍五入: -13
/*
max() :获取两个整数的较大值
min() :获取两个整数的较小值
*/
System.out.println("10和11谁大? " + Math.max(10, 11));//10和11谁大? 11
System.out.println("10和11谁小? " + Math.min(10, 11));//10和11谁小? 10
/*
pow() :获取a的b次幂[次方]
sqrt() :开平方(平方的逆运算)
cbrt() :开立方(立方的逆运算)
*/
System.out.println("2的3次方: " + Math.pow(2, 3));//2的3次方: 8.0
System.out.println("2的0.5次方: " + Math.pow(2, 0.5));//2的0.5次方: 1.0717734625362931
System.out.println("2的-2次方: " + Math.pow(2, -2));//2的-2次方: 0.25
System.out.println("4的开平方根: " + Math.sqrt(4));//4的开平方根: 2.0
System.out.println("8的开立方根: " + Math.cbrt(8));//8的开立方根: 2.0
/*
random() :无限接近于0 到 无限接近于1 的小数
*/
System.out.println("0~99的随机整数: " + Math.floor(Math.random() * 100));//0~99的随机整数: 65.0
System.out.println("1~99的随机整数: " + Math.floor(Math.random() * 100 + 1));//1~99的随机整数: 4.0
}
}
四、Random随机数
1. Random构造方法
2. Random类常用方法
3.常用方法代码
/* @Desc描述:使用Random类 */
public class TestRandom {
public static void main(String[] args) {
//创建随机数对象
Random random = new Random();
/**
* 生成4位随机数 1000-9999
* random.nextInt(int n):取自此随机数生成器序列的、在0(包括)和指定值n(不包括)之间均匀分布的int值
* random.nextInt(9000):0-8999
*/
//方法一
int num = random.nextInt(9000) + 1000;
System.out.println(num);
//方法二
int num2 = random.nextInt(10000) ;
if (num2 < 1000)
num2 += 1000;
System.out.println(num2);
//方法三
int num3;
do {
num3 = random.nextInt(10000);
} while (num3 < 1000);
System.out.println(num3);
}
}
五、传统日期类
1.Date类(已淘汰)
- jdk1.1之前
1.1 Date类构造方法
1.2 Date类常用方法
2. Calendar类日历
- 抽象类
- jdk1.1 ~jdk8
2.1 Calendar类构造方法
2.2 Calendar类常用方法
2.3 常用方法代码
import java.util.Calendar;
import java.util.Date;
/* @Desc描述:使用Calendar日历类*/
public class TestCalendar {
public static void main(String[] args) {
/*
getInstance() :使用默认时区和语言环境获得一个日历
*/
Calendar calendar=Calendar.getInstance();
/*
get(int field) :返回给定日历字段的值
YEAR :年份
MONTH :月份,从 0 开始
DAY_OF_MONTH :本月的日期
DAY_OF_WEEK :周中的日期,从 星期天 开始
DAY_OF_YEAR :在年度的日数
WEEK_OF_YEAR :在年度的周数
WEEK_OF_MONTH :在当月的周数
*/
System.out.println("年份: "+calendar.get(Calendar.YEAR));//年份: 2023
System.out.println("月份: "+(calendar.get(Calendar.MONTH)+1));//月份: 10
System.out.println("本月的日期: "+calendar.get(Calendar.DAY_OF_MONTH));//本月的日期: 19
System.out.println("周中的日期: "+calendar.get(Calendar.DAY_OF_WEEK));//周中的日期: 5
System.out.println("在年度的日数: "+calendar.get(Calendar.DAY_OF_YEAR));//在年度的日数: 292
System.out.println("在年度的周数: "+calendar.get(Calendar.WEEK_OF_YEAR));//在年度的周数: 42
System.out.println("在当月的周数: "+calendar.get(Calendar.WEEK_OF_MONTH));//月的周数: 3
/*
set() :设置年、月、日、小时、分钟、秒
*/
calendar.set(2023,10,19,16,14,35);
/*
getTime() :返回一个表示此 Calendar 时间值(从历元至现在的毫秒偏移量)的 Date 对象
*/
Date date = calendar.getTime();
/*
dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。
mon 是月份 (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec)。
dd 是一月中的某一天(01 至 31),显示为两位十进制数。
hh 是一天中的小时(00 至 23),显示为两位十进制数。
mm 是小时中的分钟(00 至 59),显示为两位十进制数。
ss 是分钟中的秒数(00 至 61),显示为两位十进制数。
zzz 是时区(并可以反映夏令时)。标准时区缩写包括方法 parse 识别的时区缩写。
如果不提供时区信息,则 zzz 为空,即根本不包括任何字符。
yyyy 是年份,显示为 4 位十进制数。
*/
System.out.println("设置的时间: "+date);//设置的时间: Sun Nov 19 16:14:35 CST 2023
}
}
3. SimpleDateFormat类
- 代表简单日期格式化,可以把日期对象、时间毫秒值格式化成我们想要的格式
3.1 SimpleDateFormat类构造方法
3.2 SimpleDateFormat类常用方法
3.3 常用方法代码
import java.text.SimpleDateFormat;
import java.util.Date;
/* @Desc描述:使用SimpleDateFormat类*/
public class TestSimpleDateFormat {
public static void main(String[] args) throws Exception{
//时间格式
String pattern="yyyy年MM月dd日 HH:mm:ss E";
SimpleDateFormat simpleDateFormat=new SimpleDateFormat(pattern);
//创建一个Date对象
Date date=new Date();
System.out.println("Date对象时间: "+date);//Date对象时间: Thu Oct 19 17:05:06 CST 2023
//日期格式化
String format = simpleDateFormat.format(date);
System.out.println("日期格式化后的时间: "+format);//日期格式化后的时间: 2023年10月19日 17:05:06 星期四
//parse() throws ParseException:从给定字符串的开始解析文本,生成 Date。
SimpleDateFormat simpleDateFormat1=new SimpleDateFormat("yyyy/MM/dd");
Date parse = simpleDateFormat1.parse("2023/10/19");
System.out.println("解析后的日期: "+parse);//解析后的日期: Thu Oct 19 00:00:00 CST 2023
}
}
六、JDK8日期类
1.JDK8日期类与JDK8前日期类的区别
2.日期时间类
- JDK1.8中,所有的日期/时间基础类都包含在java.time包中
- 是不可变的线程安全的
2.1 JDK8日期类常用类
- 都是不可变的对象
2.2 JDK8日期类常用方法
2.3常用方法代码
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
/*@Desc: 使用jdk8的时间日期类*/
public class TestDateTime {
public static void main(String[] args) {
//创建当前日期
LocalDate localDate = LocalDate.now();
System.out.println("当前日期:" + localDate);//当前日期:2023-10-19
//创建当前时间
LocalTime localTime = LocalTime.now();
System.out.println("当前时间:" + localTime);//当前时间:16:27:45.979
//创建当前日期和时间
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("当前日期和时间:" + localDateTime);//当前日期和时间:2023-10-19T16:27:45.979
//自定义日期
LocalDate localDate1 = LocalDate.of(2000, Month.JANUARY, 8);
System.out.println("自定义日期:" + localDate1);//自定义日期:2000-01-08
/*
1s【秒】 = 1000ms【毫秒】
1ms【毫秒】 = 1000μs【微秒】
1μs【微秒】 = 1000ns【纳秒】
1ns 【纳秒】= 1000ps【皮秒】
*/
//自定义时间
LocalTime localTime3 = LocalTime.of(3, 3, 3, 3);
System.out.println("自定义小时分钟秒毫秒:" + localTime3);//自定义小时分钟秒毫秒:03:03:03.000000003
//得到未来日期
LocalDate plusYears = localDate.plusYears(1);
System.out.println("未来一年:" + plusYears);//未来一年:2024-10-19
LocalDate plusMonths = localDate.plusMonths(1);
LocalDate plusDays = localDate.plusDays(1);
System.out.println("未来一天:" + plusDays);//未来一天:2023-10-20
//得到过去日期
LocalDate minusMonths = localDate.plusMonths(-1);
System.out.println("过去一月:" + minusMonths);//过去一月:2023-09-19
LocalDate minusWeeks = localDate.plusWeeks(-1);
System.out.println("过去一周:" + minusWeeks);//过去一周:2023-10-12
//得到未来时间
LocalTime plusHours = localTime.plusHours(1);
System.out.println("未来一小时:" + plusHours);//未来一小时:17:27:45.979
LocalTime plusMinutes = localTime.plusMinutes(1);
System.out.println("未来一分钟:" + plusMinutes);//未来一分钟:16:28:45.979
//得到过去时间
System.out.println("过去一秒:" + minusSeconds);//过去一秒:16:27:44.979
LocalTime minusNanos = localTime.plusNanos(-1);
System.out.println("过去一毫秒:" + minusNanos);//过去一毫秒:16:27:45.978999999
//判断2个日期对象,是否相等equals() ,在前isBefore(),在后isAfter()
LocalDate localDate2 =LocalDate.of(2023,1,2);
LocalDate localDate3 =LocalDate.of(2023,2,2);
System.out.println("'2023-1-2'是否和'2023-2-2'相等: "+localDate2.equals(localDate3));//'2023-1-2'是否和'2023-2-2'相等: false
System.out.println("'2023-1-2'是否在'2023-2-2'之前: "+localDate2.isBefore(localDate3));//'2023-1-2'是否在'2023-2-2'之前: true
System.out.println("'2023-1-2'是否在'2023-2-2'之后: "+localDate2.isAfter(localDate3));//'2023-1-2'是否在'2023-2-2'之后: false
}
3. DateTimeFormatter类
3.1 DateTimeFormatter类常用方法
3.2 常用方法代码
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/* @Desc描述:使用DateTimeFormatter日期格式化类 */
public class TestDateFormatter {
public static void main(String[] args) {
//创建当前日期和时间
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("当前日期和时间:" + localDateTime);//当前日期和时间:2023-10-19T16:27:45.979
//自定义日期格式
/*
yyyy:年
MM:月
dd:日
HH:24小时制
hh:12小时制
mm:分
ss:秒
*/
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时:mm分:秒");
//时间.format(格式化对象)
String format = localDateTime.format(dateTimeFormatter);
System.out.println("localDateTime.format的转化:" + format);
//格式化对象.format(时间)
String format1 = dateTimeFormatter.format(localDateTime);
System.out.println("dateTimeFormatter.format的转化:" + format1);
}
}
4.Zoneld时区ID
4.1时区ID概念
由于世界各个国家与地区的经度不同,各地区的时间也有所不同,因此会划分为不同的时区
- 世界标准时间UTC
- 中国标准时间UTC+8小时
4.2时区ID格式
- 洲名/城市名
- 例: Asia/Shanghai
- 国家名/城市名
- 例:American/New_York
4.3 时区ID常见方法
4.4常见方法代码
/* @Desc描述:使用时区*/
public class TestZoneld {
public static void main(String[] args) {
/*
static ZoneId systemDefault() :获取系统默认的时区
获取ZoneId对象调用getId()方法获取时区
*/
ZoneId systemDefault = ZoneId.systemDefault();
System.out.println("系统默认的时区: "+systemDefault);//系统默认的时区: Asia/Shanghai
//static Set<String> getAvailableZoneIds() :获取Java支持的时区ID
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
System.out.println(availableZoneIds);
//static ZoneId of(String zoneId) :把某个时区id封装成ZoneId对象
ZoneId of = ZoneId.of("Asia/Shanghai");
System.out.println("把'亚洲上海'封装成ZoneId对象: "+of);//把'亚洲上海'封装成ZoneId对象: Asia/Shanghai
}
}
5.ZonedDateTime带时区的时间
5.1 ZonedDateTime类常见方法
5.2常用方法代码
/* @Desc描述:使用带时区的时间的类*/
public class TestZonedDateTime {
public static void main(String[] args) {
//static ZonedDateTime now() :获取当前时区的ZonedDateTime对象
ZonedDateTime zonedDateTime=ZonedDateTime.now();
System.out.println("当前时区的时间: "+zonedDateTime);
//当前时区的时间: 2023-10-23T09:36:32.831+08:00[Asia/Shanghai]
//指定一个时区(美国纽约)
ZoneId zoneId = ZoneId.of("America/New_York");
//static ZonedDateTime now(ZoneId zone) :获取指定时区的ZonedDateTime对象
ZonedDateTime zonedDateTime1=ZonedDateTime.now(zoneId);
System.out.println("美国纽约的时间: "+zonedDateTime1);
//美国纽约的时间: 2023-10-22T21:36:32.832-04:00[America/New_York]
//世界标准时间
ZonedDateTime zonedDateTime2=ZonedDateTime.now(Clock.systemUTC());
System.out.println("世界标准时间: "+zonedDateTime2);
//世界标准时间: 2023-10-23T01:36:32.837Z
}
}
6.Instant时间戳
6.1概念
- 时间线上的某个时刻(或时间戳)–瞬间
- 通过获取Instant对象可以拿到此刻时间,该时间由两部分组成
- 从 时间原点(1970-01-01 00:00:00)开始
- 走到此刻的 总秒数+ 不够一秒的纳秒数
6.2作用
- 可以用来记录代码的执行时间,或用于记录用户操作某个事件的时间点
- 可以精确到纳秒数
- 不可变对象
- 代替Date日期类
6.3 Instant类常用方法
6.4常用方法代码
/* @Desc描述:使用时间戳类*/
public class TestInstant {
public static void main(String[] args) {
/*
static Instant now() :获取当前时间的Instant对象(世界标准时间)
底层:Clock.systemUTC().instant()
*/
Instant now = Instant.now();
System.out.println("当前时间: "+now);//当前时间: 2023-10-23T02:43:04.482Z
//long getEpochSecond() :获取从 时间原点 开始记录的 总秒数
System.out.println("总秒数: "+now.getEpochSecond());//总秒数: 1698028984
/*
int getNano() :从时间线开始,获取从第二个开始的纳秒数
不够1秒的纳秒数
*/
System.out.println("纳秒数: "+now.getNano());//纳秒数: 482000000
}
}
7.Period日期间隔
7.1作用
- 可以用于计算两个LocalDate对象 相差的年数,月数,天数
7.2 Period类常用方法
7.3常用方法代码
/* @Desc描述:使用日期间隔类 */
public class TestPeriod {
public static void main(String[] args) {
//创建指定日期
LocalDate localDate=LocalDate.of(2020,10,23);
LocalDate localDate1=LocalDate.of(2023,11,30);
//传入两个日期对象,得到Period对象
Period period = Period.between(localDate, localDate1);
System.out.println("计算相隔几年: "+period.getYears());//计算相隔几年: 3
System.out.println("计算相隔几月: "+period.getMonths());//计算相隔几月: 1
System.out.println("计算相隔几天: "+period.getDays());//计算相隔几天: 7
}
}
8.Duration时间间隔
8.1作用
- 可以用于计算两个时间对象相差的 天数,小时数,分数,秒数,纳秒数
- 支持LocalTime,LocalDateTime,Instant
8.2 Duration类常用方法
8.3常用方法代码
/* @Desc描述:使用时间间隔类*/
public class TestDuration {
public static void main(String[] args) {
//创建指定日期时间
LocalDateTime localDateTime=LocalDateTime.of(2022,10,23,11,10,10);
LocalDateTime localDateTime1=LocalDateTime.of(2023,10,23,12,11,11);
//传入两个时间对象,得到Duration对象
Duration duration=Duration.between(localDateTime,localDateTime1);
System.out.println("相隔多少天: "+duration.toDays());//相隔多少天: 365
System.out.println("相隔多少小时: "+duration.toHours());//相隔多少小时: 8761
System.out.println("相隔多少分钟: "+duration.toMinutes());//相隔多少分钟: 525661
//支持jdk9+
System.out.println("相隔多少秒: "+duration.toSeconds());
System.out.println("相隔多少纳秒: "+duration.toNanos());
}
}
9.常用时间间隔类ChronoUnit
9.1代码示意
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
/* @Desc描述:使用所有单位的时间间隔类*/
public class TestChronoUnit {
public static void main(String[] args) {
//当前时间
LocalDateTime today=LocalDateTime.now();
//本年元旦
LocalDateTime newYear=LocalDateTime.of(2023,1,1,0,0,0);
//方法展示
System.out.println("相差的年数: "+ChronoUnit.YEARS.between(newYear, today));
System.out.println("相差的月数: "+ChronoUnit.MONTHS.between(newYear, today));
System.out.println("相差的周数: "+ChronoUnit.WEEKS.between(newYear, today));
System.out.println("相差的天数: "+ChronoUnit.DAYS.between(newYear, today));
System.out.println("相差的小时数: "+ChronoUnit.HOURS.between(newYear, today));
System.out.println("相差的分数: "+ChronoUnit.MINUTES.between(newYear, today));
System.out.println("相差的秒数: "+ChronoUnit.SECONDS.between(newYear, today));
System.out.println("相差的毫秒数: "+ChronoUnit.MILLIS.between(newYear, today));
System.out.println("相差的微秒数: "+ChronoUnit.MICROS.between(newYear, today));
System.out.println("相差的纳秒数: "+ChronoUnit.NANOS.between(newYear, today));
System.out.println("相差的半天数: "+ChronoUnit.HALF_DAYS.between(newYear, today));
System.out.println("相差的十年数: "+ChronoUnit.DECADES.between(newYear, today));
System.out.println("相差的世纪数: "+ChronoUnit.CENTURIES.between(newYear, today));
System.out.println("相差的千年数: "+ChronoUnit.MILLENNIA.between(newYear, today));
System.out.println("相差的纪元数: "+ChronoUnit.ERAS.between(newYear, today));
}
}
七、System系统
1.System类常用方法
2.常用方法代码
/* @Desc描述:使用System系统类*/
public class TestSystem {
public static void main(String[] args) {
/*
currentTimeMillis() :返回当前系统的时间毫秒值形式
从时间原点 1970年1月1日 00:00:00
到运行代码的毫秒数
*/
long currentTimeMillis = System.currentTimeMillis();
System.out.println(currentTimeMillis);//1697707856013
//定义两个数组
int[] arr = new int[]{1, 2, 3, 4, 5};
int[] brr = new int[10];
/*
把a数组拷贝到b数组中
参数src :数据源数组
参数srcPos :从数据源数组的第几个索引开始拷贝
参数dest :目的地数组
参数destPos :目的地数组的索引
参数length :拷贝的个数
注意事项:①
*/
//实现 0 0 0 1 2 3 4 0 0 0
System.arraycopy(arr, 0, brr, 3, 4);
//遍历数组brr
System.out.print("\n②遍历数组brr: ");
for (int i = 0; i < brr.length; i++) {
System.out.print(brr[i] + " ");
}//②遍历数组brr: 0 0 0 1 2 3 4 0 0 0
/*
exit() :终止当前运行的Java虚拟机
0 :表示当前虚拟机正常停止
非0 :表示当前虚拟机异常停止
*/
System.exit(0);
System.out.println("是否执行到这?");
}
}
3.拷贝数组注意事项
①如果 数据源数组 和 目的地数组 都是 基本数据类型
那么两者的类型 必须保持一致, 否则会报错
②如果 数据源数组 和 目的地数组 都是 引用数据类型
那么 子类类型 可以赋值给 父类类型
八、Runtime虚拟机运行环境
1. Runtime类常用方法
2.常用方法代码
import java.io.IOException;
/* @Desc描述:使用Runtime虚拟机运行环境类*/
public class TestRuntime {
public static void main(String[] args) throws IOException {
//getRuntime() :获取Runtime对象
Runtime runtime = Runtime.getRuntime();
//availableProcessors() :获取CPU的线程数
System.out.println("当前电脑的逻辑处理器个数: " + runtime.availableProcessors());
//当前电脑的逻辑处理器个数: 16
/*
1KB=1024B,1MB=1024KB,1GB=1024MB
*/
//maxMemory() :JVM能从系统中获取总内存大小(单位byte)
System.out.println("JVM能从系统中获取总内存大小: " + runtime.maxMemory() / 1024 / 1024 / 1024 + "G");
//JVM能从系统中获取总内存大小: 3G
//totalMemory() :JVM已经从系统中获取总内存大小(单位byte)
System.out.println("JVM已经从系统中获取总内存大小: " + runtime.totalMemory() / 1024 / 1024 + "MB");
//JVM已经从系统中获取总内存大小: 243MB
//freeMemory() :JVM剩余内存大小(单位byte)
System.out.println("JVM剩余内存大小: " + runtime.freeMemory() / 1024 / 1024 + "MB");
//JVM剩余内存大小: 238MB
/*
exec(String command) throws IOException :运行cmd命令
-打开软件 例:notepad 笔记本
-关机 shutdown -s 默认1分钟之后关机
-自定义关机 shutdown -s -t 指定时间(s)
-取消关机操作 shutdown -a
-关机并重启 shutdown -r
*/
runtime.exec("notepad");
/*
exit() :停止虚拟机
System.exit的底层
*/
Runtime.getRuntime().exit(0);
}
}
九、Object类
1. Object类无参构造
顶级父类中只有无参构造
public Object(){}
2. Object类成员方法
3. toString()代码示意
/*
toString() :返回对象的字符串表示形式
包名 @ 对象地址值
底层:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
*/
Object object=new Object();
String str=object.toString();
System.out.println(str);//java.lang.Object@4554617c
/*
System :类名
out :静态变量
System.out :获取打印的对象
println() 底层:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
*/
System.out.println(object);//java.lang.Object@4554617c
/*
重写toString() : 将不在打印地址值,打印的属性值
public String toString() {
return "Student{name = " + name + ", age = " + age + "}";
}
*/
Student student=new Student("张三",11);
System.out.println(student);//Student{name = null, age = 0}
4. equals()代码示意
/*
equals() :比较两个对象是否相等
底层: 比较的是对象的地址值
public boolean equals(Object obj) {
return (this == obj);
}
*/
Student student1=new Student("张三",11);
boolean result = student1.equals(student);
System.out.println("创建两个对象是否相等:"+result);//创建两个对象是否相等:false
/*
重写equals() :比较对象内部属性值是否相等
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
*/
boolean result1 =student1.equals(student);
System.out.println("重写equals()后的对象比较是否相等:"+result1);
//重写equals()后的对象比较是否相等:true
String s="adc";
StringBuffer stringBuffer=new StringBuffer("adc");
/*
因为equals方法是被字符串调用的,所以要看String类中的equals方法
字符串中的equals方法,先判断参数是否是 字符串
如果是字符串,再比较内部的属性
如果不是,则直接返回false
*/
System.out.println(s.equals(stringBuffer));//false
/*
因为equals方法是被StringBuffer调用的,所以要看StringBuffer类中的equals方法
StringBuffer里没有重写equals方法,默认继承Object类的equals方法
在Object类中的equals方法 使用==号比较两个对象的地址值
*/
System.out.println(stringBuffer.equals(s));//false
5. clone()对象克隆
把A对象的属性值完全拷贝给B对象,也叫对象拷贝,对象复制
/*@Desc描述:测试Object类中的clone方法*/
public class TestClone {
public static void main(String[] args) throws CloneNotSupportedException {
/*
创建一个被克隆的对象
因为clone方法是protected的,只能在同包和其他包的子类中使用
如果使用需要重写clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
//调用父类中的clone方法
//相当于让Java帮我们克隆一个对象,并把克隆之后的对象返回出去
return super.clone();
}
*/
/*
public class Student implements Cloneable
当一个接口里面没有抽象方法的时候,表名当前的接口是一个标记性接口
Cloneable 表示一旦实现,那么当前类的对象可以被克隆
*/
Student student=new Student("张三",11);
System.out.println("被克隆的对象:"+student);//被克隆的对象:Student{name = 张三, age = 11}
Student student1= (Student) student.clone();
System.out.println("克隆的对象:"+student1);//克隆的对象:Student{name = 张三, age = 11}
}
}
5.1使用步骤
①重写Object类中的clone()方法
②让被克隆的对象实现Cloneable接口
③创建原对象并调用clone()方法【默认浅克隆】
5.2浅克隆
1)特点
- 基本数据类型直接拷贝变量记录的数据值
- 引用数据类型直接拷贝变量记录的地址值
2)浅克隆验证
//验证Object类中的克隆是浅克隆
int[] arr=student.getData();
arr[0]=100;
System.out.println(student);
//Student{name = 张三, age = 11, data = [100 ,2 ,3 ,4 ]}
System.out.println(student1);
//Student{name = 张三, age = 11, data = [100 ,2 ,3 ,4 ]}
3)浅克隆内存图
对于数组,两个对象使用同一个数组
特点:如果其中一个对象对数组中的数据发生改变,另一个数组再次访问该数组,就是修改后的数组
5.3深克隆
1)特点
- 基本数据类型直接拷贝变量记录的数据值
- 不是new出来的引用数据类型会复用串池中已存在的地址值【字符串复用】
- new出来的引用数据类型(例:数组),会重新创建新的数组
2)深克隆方法重写
- 第三方工具
- 方法重写
/*深克隆重写方法 */
@Override
protected Object clone() throws CloneNotSupportedException {
//1.先把被克隆对象的数组获取出来
int[] data=this.data;
//2.创建新的数组
int[] newData=new int[data.length];
//3.拷贝数组中的数据 ?此处换成二维数组有隐患
for (int i = 0; i < data.length; i++) {
newData[i]=data[i];
}
//4.调用父类中的clone方法克隆对象
Student student= (Student) super.clone();
//5.因为父类中的克隆方法是浅克隆,替换克隆出来对象中数组的地址值
student.data=newData;
return student;
}
------>验证
int[] data=new int[]{1,2,3,4};
Student student=new Student("张三",11,data);
System.out.println("被克隆的对象:"+student);
//被克隆的对象:Student{name = 张三, age = 11, data = [1 ,2 ,3 ,4 ]}
Student student1= (Student) student.clone();
System.out.println("克隆的对象:"+student1);
//克隆的对象:Student{name = 张三, age = 11, data = [1 ,2 ,3 ,4 ]}
//修改被克隆的对象的数组的0下标
int[] arr=student.getData();
arr[0]=100;
System.out.println(student);
//Student{name = 张三, age = 11, data = [100 ,2 ,3 ,4 ]}
System.out.println(student1);
// Student{name = 张三, age = 11, data = [1 ,2 ,3 ,4 ]}
3)深克隆内存图
十、BigInteger类
1. BigInteger构造方法
对象一旦创建,内部记录的值不能发生改变
2.常用构造方法代码
import java.math.BigInteger;
import java.util.Random;
/*@Desc描述:使用BigInteger大整数的构造方法 */
public class TestBigIntegerConstructors {
public static void main(String[] args) {
/*
public BigInteger(int numBits, Random rnd)
获取随机大整数,范围 :【0~2的numBits次方-1】
0~2的4次方(16)之间的大整数
*/
BigInteger bigInteger = new BigInteger(4, new Random());
System.out.println("随机大整数: " + bigInteger);//随机大整数: 8
/*
public BigInteger(String val) {
this(val, 10);
}
获取指定大整数。且只能写整数,不能写小数或者String类型
*/
BigInteger bigInteger1 = new BigInteger("100");
System.out.println("获取指定的大整数: " + bigInteger1);//获取指定的大整数: 100
/*
public BigInteger(String val, int radix)
获取指定进制的大整数
1.字符串中的数字必须是整数
2.字符串中的数字必须要跟进制吻合
例:
如果是2进制的时候,不能书写除0和1的值,因为二进制里只有0和1
*/
BigInteger bigInteger2 = new BigInteger("123", 10);
System.out.println("10进制的123: " + bigInteger2);//10进制的123: 123
BigInteger bigInteger3 = new BigInteger("100", 2);
System.out.println("2进制的100: " + bigInteger3);//2进制的100: 4
/*
public static BigInteger valueOf(long val)
静态方法获取BigInteger的对象
1.能表示的范围较小,在long的取值范围之内
2.在内部对常用的数字 -16~16进行优化
提前把-16~16先创建好BigInteger的对象,如果多次获取不会重新创建新的对象
*/
BigInteger bigInteger4 = BigInteger.valueOf(100);
System.out.println("静态方法valueOf获取的对象: " + bigInteger4);//静态方法valueOf获取的对象: 100
//1.能表示的范围较小,在long的取值范围之内
System.out.println(Long.MAX_VALUE);//9223372036854775807
//BigInteger bigInteger5 = BigInteger.valueOf(9223372036854775808L);
//编译报错:Long number too large
//2.在内部对常用的数字 -16~16进行优化
BigInteger b6 = BigInteger.valueOf(16);
BigInteger b7 = BigInteger.valueOf(16);
System.out.println("16的地址值是否相等: " + (b6 == b7));//16的地址值是否相等: true
BigInteger b8 = BigInteger.valueOf(17);
BigInteger b9 = BigInteger.valueOf(17);
System.out.println("17的地址值是否相等: " + (b8 == b9));//17的地址值是否相等: false
/*
对象一旦创建,内部记录的值不能发生改变
*/
BigInteger b10 = BigInteger.valueOf(1);
BigInteger b11 = BigInteger.valueOf(2);
//不会改变参加计算的BigInteger对象的内部值,会产生一个新的对象去记录
BigInteger add = b10.add(b11);
System.out.println("两个bigInteger对象相加结果: "+add);
}
}
3. BigInteger常用方法
4.常用方法代码
import java.math.BigInteger;
/* @Desc描述:使用BigInteger的常用方法*/
public class TestBigIntegerMethods {
public static void main(String[] args) {
//创建2个操作的BigInteger对象
BigInteger b1=BigInteger.valueOf(10);
BigInteger b2=BigInteger.valueOf(3);
/*
add() :加法
subtract() :减法
multiply() :乘法
*/
BigInteger add = b1.add(b2);
System.out.println("10+3加法结果: "+add);//10+3加法结果: 13
//除法
BigInteger divide = b1.divide(b2);
System.out.println("10/2除法结果: "+divide);//10/3除法结果: 3
//除法获取商和余数
BigInteger[] arr = b1.divideAndRemainder(b2);
System.out.println("数组的长度: "+arr.length);//数组的长度: 2
System.out.println("除法获取的商:"+arr[0]+",获取的余数:"+arr[1]);
//除法获取的商:3,获取的余数:1
//是否相等
boolean equals = b1.equals(b2);
System.out.println("10和3是否相等: "+equals);//10和3是否相等: false
//较大值,不会创建新的对象
BigInteger max = b1.max(b2);
System.out.println("10和3谁大: "+max);//10和3谁大: 10
//转换为int类型
int intValue = b1.intValue();
System.out.println("int范围内的转换: "+intValue);
//int范围内的转换: 10
BigInteger b3=BigInteger.valueOf(2147483648L);
int intValue1 = b3.intValue();
System.out.println("超出int范围的转换:" +intValue1);
//超出int范围的转换:-2147483648
//转换为double类型
double doubleValue = b1.doubleValue();
System.out.println("double范围内的转换: " +doubleValue);
//double范围内的转换: 10.0
}
}
5. BigInteger底层存储方式
//符号位,1表示正数,-1表示负数,0的符号位为0
final int signum;
//int数组,从index=0开始表示大数的最高位
final int[] mag;
//大数的bit个数加1,默认值为0,当需要时才会被初始化
@Deprecated
private int bitCount;
@Deprecated
private int bitLength;
@Deprecated
private int lowestSetBit;
@Deprecated
private int firstNonzeroIntNum;
十一、BigDecimal类
1. BigDecimal类构造方法
表示较大的小数和解决小数运算精度失真问题
2.常用构造方法代码
import java.math.BigDecimal;
/* @Desc描述:使用BigInteger小数的构造方法*/
public class TestBigDecimalConstructors {
public static void main(String[] args) {
//1.通过传递double类型的小数来创建对象
//不精确的数据,不建议使用
BigDecimal bigDecimal = new BigDecimal(0.1);
BigDecimal bigDecimal1 = new BigDecimal(0.9);
System.out.println(bigDecimal);
System.out.println(bigDecimal1);
/**
* 如果要表示的数字不超过double取值范围,使用静态方法
* 如果要表示的数字超过double取值范围,使用字符串表示的构造方法
* 如果传递的是0~10之间的整数,包括0和10,那么方法会返回已经创建好的对象,不会重新new
*/
//2.通过传递字符串表示的小数来创建对象
BigDecimal bd1 = new BigDecimal("0.1");
BigDecimal bd2 = new BigDecimal("0.9");
System.out.println("字符串小数0.1->" + bd1);//字符串小数0.1->0.1
System.out.println("字符串小数0.9->" + bd2);//字符串小数0.9->0.9
BigDecimal add = bd1.add(bd2);
System.out.println("相加结果:" + add);//相加结果:1.0
//3.通过静态方法获取对象
BigDecimal valueOf = BigDecimal.valueOf(10);
System.out.println("静态方法获取的值:"+valueOf);//静态方法获取的值:10
//4.验证是否同一个地址
BigDecimal valueOf1 = BigDecimal.valueOf(10);
BigDecimal valueOf2 = BigDecimal.valueOf(10);
/*
只要是double类型的参数,都会直接返回一个新的对象
public static BigDecimal valueOf(double val) {
return new BigDecimal(Double.toString(val));
}
*/
BigDecimal valueOf3 = BigDecimal.valueOf(10.0);
System.out.println("静态方法获取的10的对象是否在同一个地址: "+(valueOf1==valueOf2));
//静态方法获取的10的对象是否在同一个地址: true
System.out.println("静态方法获取整数10对象和小数10.0是否在同一个地址: "+(valueOf1==valueOf3));
//静态方法获取整数10对象和小数10.0是否在同一个地址: false
}
}
3. BigDecimal常用方法
4.常用方法代码
import java.math.BigDecimal;
import java.math.RoundingMode;
/*@Desc描述:使用BigDecimal常用方法*/
public class TestBigDecimalMethods {
public static void main(String[] args) {
//创建2个对象
BigDecimal bigDecimal=new BigDecimal(10.0);
BigDecimal bd=new BigDecimal(3.0);
//加法
BigDecimal add = bigDecimal.add(bd);
System.out.println("加法结果: "+add);//加法结果: 13
//减法
BigDecimal subtract = bigDecimal.subtract(bd);
System.out.println("减法结果: "+subtract);//减法结果: 7
//乘法
BigDecimal multiply = bigDecimal.multiply(bd);
System.out.println("乘法结果: "+multiply);//乘法结果: 30
//舍入模式除法
BigDecimal divide1 = bigDecimal.divide(bd, 3, RoundingMode.HALF_UP);
System.out.println("四舍五入保留3位小数: "+divide1);//四舍五入保留3位小数: 3.333
}
}