目录
前言
API(Application Programming Interface):应用程序编程接口
简单理解:API就是别人已经写好的东西,我们不需要自己编写,直接使用即可.
JDK中提供的各种功能的类
java.lang包使用中不需要导包
在本章中,我们将讨论:
- Math
- System
- Object
- Objects
- BigInteger
- BigDecimal
- 包装类
- Arrays
- Lambda表达式
- JDK8时间类
一.Math类
首先我们要知道,一个类中应该有成员变量,构造方法,成员方法等,当一个类中的成员方法被static修饰后,就不需要创建这个类的对象,可以直接用类名.来调用,Math类就是这样的一种类,他的成员方法全部是用static修饰,可以直接使用Math.调用
成员变量
成员方法
补充
sqrt返回平方根,返回值是double类型
cbrt返回立方根,返回值是double类型
ceil往数轴正方向取整
floor往数轴反方向取整
二.System类
在介绍System类之前,我们简单了解一个小故事,是关于计算机中的时间原点的
成员方法
System.exit();
System.currentTimeMillis();获取1970年1月1日到现在有多少毫秒
作用:可以相减判断程序执行了多久
arraycopy()拷贝数组
拓展:
在Arrays类中也有两个方法拷贝数组,传入参数不同,按需使用
三.Object类
Object是所有类的父类,所有类都继承他的方法
成员方法不是静态的,必须先创建对象,再用对象调用方法
1.toString
就是把一个对象变成字符串表现形式
sout源码就是一个toString方法
但在Object中,toString返回的是对象的地址值
当我们需要对象的成员变量属性值而不需要地址值的时候必须重写Object的toString方法
在重写的方法中,把对象的属性值进行拼接就好
在一个标准的JavaBean中,我们一般需要去重写toString方法来使他返回属性值而不是地址值
所以我们不重写toString的时候,用toString打印和直接sout打印的值一样
2.equals
比较地址值
需要比较属性值的时候需要重写方法
public boolean equals(Object obj) {
return (this == obj);
}
这个方法只是检查两个对象是否是同一个对象(即引用是否相同).
注意:
在字符串String中的equals方法里,先判断传递的参数是不是一个String类型,如果不是,返回false
如果是再去比较属性值,因为String类里重写了equals方法
StringBuilder类里没有重写equals方法,使用的是Object方法,所以equals比较的是地址值
3.clone
把方法调用对象的属性值(成员变量)完全拷贝给另一个对象
注意克隆的是成员变量,成员方法没有被克隆.
要使用clone方法,对象的类必须实现Cloneable这个接口,Cloneable接口是一个标记性接口,没有定义任何方法,他的存在只是为了表明该类支持克隆操作.
public interface Cloneable{}//标记性接口
表示一旦实现了,那么当前类的对象就可以被克隆,没有实现当前类的对象就不能被克隆
public class User implements Cloneable{}//User类实现标记接口,表示可以被克隆
由于Object类中的clone方法是被protected修饰的,因此需要在子类中将其重写
方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去
书写步骤:
1.重写Object中的clone方法
2.让JavaBean类实现Cloneable接口
3.创建原对象并调用clone就可以了
User u2 = (User)u1.clone();//创建u2对象,把u1的属性值全部克隆给u2
3.1浅克隆
把u1引用数据类型的地址值克隆给u2
u1的改变会影响u2
默认情况下,Object类的clone方法执行的是浅克隆,浅克隆会创建一个新的对象,并将原对象的所有成员变量复制到新对象中,对于基本数据类型,会创建新的副本,但对于引用数据类型,新对象中的引用将指向与原对象相同的对象
3.3深克隆
基本数据类型会直接复制
引用数据类型会在堆内存创建新的对象,赋值新的地址值
但是直接赋值(=)的字符串会在串池中,地址值不变,会复用.
四.Objects类
主要是用来做非空判断的
boolean result = Objects.equals(s1,s2);
equals底层会判断s1是否为null,如果为null,直接返回false
如果s1不为null,那么就会用s1调用Object中的equals方法
如果没有重写,比较地址值,如果重写了,比较属性值
五.BigInteger类
大整数
BigInteger类的对象一旦创建,不能被修改
构造方法,创建对象时使用
BigInteger bi1 = new BigInteger("9999999999");//当创建整数大于long类型的时候用
BigInteger bi2 = BigInteger.valueOf(99999);//当创建整数小于等于long类型的时候用
传递的字符串内容只能是整数
通过静态方法获取的大整数内部优化:
在内部提前把-16~16的整数先创建好BigInteger对象,如果多次获取就不会重新创建新的
成员方法
只要进行计算都会产生一个新的BigInteger对象
底层存储方式
在java中,整数有四种类型:byte1个字节,short 2个字节,int 4个字节,long 8个字节
1个字节byte = 8个比特bit
把大整数变成补码的形式,以32位为一组,把每组的十进制数字存到数组int[]mag中
为什么是32位呢,因为数组的类型是int.int是4个字节,32个bit位,所以最多能存放int类型的十进制
成员变量:
int signum(存储大整数的正负号) -1 负 0/1 正
int [] mag
六.BigDecimal类
大浮点数
BigDecimal类的对象一旦创建,不能被修改
当我们使用小数去进行计算的时候,会出现不精确的现象,为什么会这样呢?
让我们来看一下小数在计算机中是如何计算的
我们发现,小数部分在转换成二进制的时候位数是很庞大的,而java中存放小数的类型只有float和double,而他们给小数部分存放位数的bit位往往没有那么大,所以多出来的位数就会被省略,从而导致数据不精确
所以BigDecima的作用不但可以表示很大的小数,而且用做小数的精确计算
同样的,当我们要创建BigDecima对象的时候
如果要表示小数长度不超过double的时候,可以用BigDecimal类的静态方法去获取对象
BigDecimal bd = BigDecimal.valueOf(0.32);//当创建小数小于double的时候
当要表示小数长度超过double的时候,要用构造方法创建BigDecimal对象
BigDecimal bd = new BigDecimal("0.3222222");//当创建小数大于double的时候
构造方法可以传递字符串也可以传递小数和整数,但返回结果也会不精确,所以建议只传递字符串
同样的,java在BigDecima的静态方法内部也提前把0~10的整数先创建好BigDecima对象,如果多次获取就不会重新创建新的,注意是整数
成员方法
底层存储
遍历字符串,得到每一个字符,转换成asc码,存储到数组(byte类型的数组)中
七.包装类
基本数据类型对应的引用数据类型.
就是把基本数据类型变成对象
JDK5以前创建包装类对象
包装类没有构造方法,只能通过静态方法创建对象
Integer i = Integer.valueOf(10);
底层原理
这种方法虽然可以正常打印127,但在Java 10 及更高版本中被删除,因为是new出来的,会浪费空间
JDK5以后创建包装类对象
把Integer和int看成一个东西就行,会在底层自动完成装箱拆箱的操作
自动装箱:把基本数据类型自动变成其对应的包装类
自动拆箱:把包装类自动变成其对应的基本数据类型
Integer i = 10;//自动装箱
在底层,还会调用valueof静态方法得到一个Integer对象,只不过这个动作不需要我们自己去操作了
Integer i = Integer.valueOf(10);
int i1 = i;//自动拆箱
成员方法
八.Arrays类
成员方法
sort(数组,规则)
规则Comparator是一个匿名内部类
sort的底层原理是算法中的快速排序
而sort(数组,规则)这个方法的底层原理是利用插入排序+二分查找的方式进行排序的,接下来我们梳理一下sort(数组,规则)这个方法的底层原理
o1:表示无序列表中的元素
o2:表示有序列表中的元素
第一个0索引元素是有序序列
遍历无序序列,取出第一个元素和有序序列比较,用o1(无序元素)-o2(有序元素)
前<----------------后
结果如果是负数,表示o1<o2,取出的无序元素小,要放到前面
结果如果是正数,表示o1>o2,取出的无序元素大,要放到后面
结果如果是0,表示o1=o2,取出的无序元素和有序元素相等,也要放到后面
当有序元素越来越多的时候,o1就会利用二分查找来和中间的元素比较
结论:
o1-o2,升序
o2-o1,降序
九.Lambda表达式
简化匿名内部类
如果只有一个参数,那么()也可以省略
十.JDK8时间类
JDK7的时间类对象会发生改变,多线程环境下会导致数据安全问题
所以我们只了解JDK8的时间类即可
JDK8时间日期对象都是不可变的,改变时间会产生新的时间类对象
1.Date类
ZoneId类
成员方法
Instant类
成员方法
ZoneDateTime类
成员方法
2.日期格式化类
DateTimeFormatter类
解析:字符串->日期类
格式化:日期类->字符串
3.Calendar日历类
日历类(最常用)
LocalDate 年月日
LocalTime 时分秒
LocalDateTime 年月日时分秒
成员方法
转换
4.时间间隔工具类
成员方法
静态方法between(date1,date2)
Period用get获取间隔
Duration用to获取间隔
重点掌握ChronoUnit