Java学习笔记(三)
文章目录
- Java学习笔记(三)
- 1 常用API
- 1.1 类 Math
- 1.1.1 abs
- 1.1.2 ceil和floor
- 1.2 System
- 1.2.1 exit()
- 1.2.2 currentTimeMillis()
- 1.2.3 arraycopy()
- 1.3 Runtime
- 1.4 Object
- 1.4.1 System.out.println底层原理
- 1.4.2 equals
- String类重写的equals方法
- 1.5 对象克隆
- 1.5.1 cloneable接口
- 1.5.2 浅克隆(Object的clone是浅克隆)
- 1.5.3 深克隆
- 使用第三方工具gson-2.6.2.jar实现深克隆
- 1.6 工具类Objects
- 1.6.1 Objects.equals
- 1.7 BigInteger和BigDecimal
- 1.7.1 BigInteger创建对象方法
- 1.7.2 BigInteger常见成员方法
1 常用API
1.1 类 Math
- 用于数学计算的工具类
- 私有化构造方法,所有方法都是静态
内容 | 作用 |
---|---|
E | e(即自然对数的底数)的 double 值。 |
PI | pi(即圆的周长与直径之比)的 double 值。 |
abs(double a) | 返回a的绝对值 |
cbrt(double a) | 返回a的立方根 |
exp(double a) | 返回e的a次幂 |
log(double a) | 返回a的自然对数(底数是e) |
log10(double a) | 返回a的对数(底数是10) |
max(a,b) | 返回a和b中较大的一个 |
min(a,b) | 返回a和b中较小的一个 |
pow(a,b) | 返回a的b次幂 |
log(double a) | 返回a的自然对数(底数是e) |
random() | 返回double的随机数,范围是[0.0,1.0) |
sqrt(a) | 返回a的平方根 |
ceil(double a) | 向上取整,7.2->8 |
floor(double a) | 向下取整,7.9->7 |
round(double a) | 四舍五入 |
1.1.1 abs
public class test53 {
public static void main(String[] args) {
//int的范围是:-2147483648 ~ 2147483647
System.out.println(Math.abs(-2147483648)); //-2147483648
System.out.println(Math.absExact(-2147483648)); //JDK15以后,会报错
}
}
1.1.2 ceil和floor
public class test53 {
public static void main(String[] args) {
System.out.println(Math.ceil(13.34)); //14.0
System.out.println(Math.ceil(13.94)); //14.0
System.out.println(Math.ceil(-13.34)); //-13.0
System.out.println(Math.ceil(-13.94)); //-13.0
System.out.println(Math.floor(13.34)); //13.0
System.out.println(Math.floor(13.94)); //13.0
System.out.println(Math.floor(-13.34)); //-14.0
System.out.println(Math.floor(-13.34)); //-14.0
}
}
1.2 System
方法 | 作用 |
---|---|
exit() | 终止当前正在运行的 Java 虚拟机 |
currentTimeMillis() | 返回以毫秒为单位的当前时间(1s=1000ms) |
arraycopy() | 从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束 |
1.2.1 exit()
public static void exit(int status)
方法形参:状态码
- 0:表示当前虚拟机正常停止
- 非0:表示当前虚拟机异常停止
1.2.2 currentTimeMillis()
public static long currentTimeMillis()
返回:当前时间与 1970 年 1 月 1 日0点之间的时间差(以毫秒为单位测量)
- 可以获得程序运行的时间
1.2.3 arraycopy()
public static void arraycopy(数据源数据,起始索引,目的地数组,起始索引,拷贝个数)
- 如果数据源数组和目的地数组都是基本数据类型,两者类型必须保持一致,否则会报错
- 拷贝的时候要考虑数据长度,超出长度也报错
- 如果数据源数组和目的地数组都是引用数据类型,那么子类类型可以复制给父类类型
public class test {
public static void main(String[] args) {
Student s1=new Student("cjm",22);
Student s2=new Student("cjm",22);
Student s3=new Student("cjm",22);
Student[] arr={s1,s2,s3};
Person[] parr=new Person[3];
System.arraycopy(arr,0,parr,0,3);
StringBuilder sb=new StringBuilder();
for(Person i:parr){
sb.append(i.getName()).append(" ").append(i.getAge()).append("\n");
}
System.out.println(sb);
for (int i = 0; i < parr.length; i++) {
Student stu= (Student) parr[i]; //强制转换
sb.append(stu.getName()).append(" ").append(stu.getAge()).append("\n");
}
System.out.println(sb);
}
}
1.3 Runtime
可以通过 getRuntime
方法获取。
方法 | 作用 |
---|---|
exit() | 终止当前正在运行的 Java 虚拟机 |
availableProcessors() | 获得CPU线程数 |
maxMemory() | JVM能从系统中获取的总内存大小(单位byte) |
totalMemory() | JVM已经从系统中获取的总内存大小(单位byte) |
freeMemory() | JVM剩余内存大小(单位byte) |
exec(String command) | 运行cmd命令 |
public class test54 {
public static void main(String[] args) {
Runtime r1=Runtime.getRuntime();
Runtime r2=Runtime.getRuntime();
System.out.println(r1==r2); //true
//获得CPU线程数
System.out.println(Runtime.getRuntime().availableProcessors()); //8
//JVM能从系统中获取的总内存大小(单位byte)
System.out.println(Runtime.getRuntime().maxMemory()/1024/1024); //3596 --- 3.5G
//JVM已经从系统中获取的总内存大小(单位byte)
System.out.println(Runtime.getRuntime().totalMemory()/1024/1024); //243M
//JVM剩余内存大小(单位byte)
System.out.println(Runtime.getRuntime().freeMemory()/1024/1024); //238M
Runtime.getRuntime().exit(0); //终止当前正在运行的虚拟机
}
}
import java.io.IOException;
public class test55 {
public static void main(String[] args) throws IOException {
//运行cmd命令
//shutdown:关机
//加上参数才能执行:
//-s :默认一分钟后关机
//-s -t指定关机时间:XXX秒后关机
//-a:取消关机操作
//-r:关机并重启
Runtime.getRuntime().exec("shutdown -s -t 3600"); //一个小时后关机
Runtime.getRuntime().exec("shutdown -a"); //取消关机
}
}
1.4 Object
Java中的顶级父类,所有的类都直接或间接继承于Object
public Object(){
}
- 顶级父类Object中只有无参构造
public Student() {
super(); //对于每一个类的空参构造隐含语句,默认访问父类的无参构造
}
方法 | 作用 |
---|---|
public String toString() | 该对象的字符串表示形式 |
public boolean equals(Object obj) | 如果此对象与 obj 参数相同,则返回 true;否则返回 false |
protected Object clone() | 此实例的一个副本 |
1.4.1 System.out.println底层原理
public class test {
public static void main(String[] args) {
Student s=new Student();
String str=s.toString();
System.out.println(str); //test11.Student@1b6d3586
System.out.println(s); //test11.Student@1b6d3586
}
}
//System源码
public final class System{
public final static PrintStream out = null;
}
//println源码
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
//String.valueOf源码
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
- System:类名
- out:System类中的一个静态变量
- System.out :获取要打印的对象
- println:方法(底层会将对象变成字符串,打印输出在控制台,并且换行处理)
总结:
即默认情况下,打印对象调用Object的toString方法输出的是地址值
想要输出对象的属性值,即在对象所属的类中重写Object的toString方法
1.4.2 equals
equals(Object obj) 默认比较的是对象的地址值
如果要想比较对象的属性值,则重写Object的equals方法
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
//重写Object的equals方法
@Override
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);
}
}
String类重写的equals方法
public class test56 {
public static void main(String[] args) {
String str="cjm是大傻逼";
StringBuilder sb=new StringBuilder("cjm是大傻逼");
System.out.println(str.equals(sb)); //false
System.out.println(sb.equals(str)); //false
}
}
//String的equals源码
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
String类重写的equals方法:
-
先判断是不是字符串,是再比较对象的内部属性值,不是直接return false
-
StringBuilder的equals方法直接继承于Object类,比较的是对象的地址值
1.5 对象克隆
clone()会帮我们创建一个对象,并把源对象中的数据拷贝过去
实现步骤:
- 重写Object中的clone方法
- 让JavaBean类实现cloneable接口
- 创建对象并调用clone方法
public class Student implements Cloneable{
private String name;
private int age;
...
@Override
protected Object clone() throws CloneNotSupportedException {
//调用父类中的clone方法
//克隆一个对象并返回
return super.clone();
}
}
public class test {
public static void main(String[] args) throws CloneNotSupportedException {
Student stu=new Student("cjm",22);
Student stu1= (Student) stu.clone();
//因为clone返回的还是Object的克隆的对象,所以要强转成Student类型
System.out.println(stu1.getName()+stu1.getAge());
}
}
1.5.1 cloneable接口
- 无抽象方法,为标记性接口
- 表示一旦实现,当前类的对象可以被克隆,否则不能被克隆
public interface Cloneable {
}
1.5.2 浅克隆(Object的clone是浅克隆)
- 不管对象内部的属性是基本数据类型还是引用数据类型,都完全拷贝过来
浅克隆出现的问题:
- 克隆的对象以及源对象都指向同一个地址,一旦其中一个对象对地址属性值进行修改,则二者的属性值都是修改过后的值
1.5.3 深克隆
- 基本数据类型——拷贝过来
- 字符串——复用串池
- 引用数据类型——创建新的
- 不是new出来的字符串会复用串池里面的内容
想要实现深克隆,要在类中重写clone方法:
public class Student implements Cloneable{
private String name;
private int age;
private int[] arr=new int[10];
public Student() {
}
public Student(String name, int age, int[] arr) {
this.name = name;
this.age = age;
this.arr = arr;
}
...
public String getArr() {
StringBuilder sb=new StringBuilder();
sb.append("{");
for(int i=0;i<arr.length;i++){
if(i==arr.length-1){
sb.append(arr[i]);
}else{
sb.append(arr[i]).append(",");
}
}
sb.append("}");
return sb.toString();
}
public void setArr(int[] arr) {
this.arr = arr;
}
@Override
protected Object clone() throws CloneNotSupportedException {
int[] arrs=new int[arr.length];
for(int i=0;i<arr.length;i++){
arrs[i]=arr[i];
}
Student stu= (Student) super.clone(); //先用Object克隆一个新对象
stu.arr=arrs; //再替换Object对象的地址值
return stu; //将替换过后的克隆对象返回
}
}
public class test {
public static void main(String[] args) throws CloneNotSupportedException {
int[] arr={1,2,3,4,5,6,7,8,9,10};
Student stu=new Student("cjm",22,arr);
Student stu1= (Student) stu.clone();
//因为clone返回的还是Object的克隆的对象,所以要强转成Student类型
arr[0]=100;
System.out.println(stu.getName()+" "+stu.getAge()+" "+stu.getArr());
//cjm 22 {100,2,3,4,5,6,7,8,9,10}
System.out.println(stu1.getName()+" "+stu1.getAge()+" "+stu1.getArr());
//cjm 22 {1,2,3,4,5,6,7,8,9,10}
}
}
使用第三方工具gson-2.6.2.jar实现深克隆
public class test {
public static void main(String[] args) throws CloneNotSupportedException {
int[] arr={1,2,3,4,5,6,7,8,9,10};
Student stu=new Student("cjm",22,arr);
Gson gson=new Gson();
String str=gson.toJson(stu); //将克隆的对象变成一个字符串
System.out.println(str);
//{"name":"cjm","age":22,"arr":[100,2,3,4,5,6,7,8,9,10]}
Student stu1=gson.fromJson(str,Student.class); //返回克隆后的对象
arr[0]=100;
System.out.println(stu.getName()+" "+stu.getAge()+" "+stu.getArr());
//cjm 22 {100,2,3,4,5,6,7,8,9,10}
System.out.println(stu1.getName()+" "+stu1.getAge()+" "+stu1.getArr());
//cjm 22 {1,2,3,4,5,6,7,8,9,10}
}
}
1.6 工具类Objects
方法 | 功能 |
---|---|
equals(a,b) | 先判断是否为空,空和不相等返回false,相等返回true |
isNull() | 判断对象是否为null,是null返回true,否返回false |
nonNull() | 判断对象是否为null,不是null返回true,null返回false |
1.6.1 Objects.equals
import java.util.Objects;
public class test {
public static void main(String[] args) throws CloneNotSupportedException {
int[] arr={1,2,3,4,5,6,7,8,9,10};
Student stu=new Student("cjm",22,arr);
Student stu2=null;
Student stu3=null;
System.out.println(Objects.equals(stu,stu2)); //false
System.out.println(Objects.equals(stu2,stu3)); //true
}
}
先判断是否为null,否,则调用对象的equals方法进行比较
注意:
==比较两个对象比较的是地址值
1.7 BigInteger和BigDecimal
1.7.1 BigInteger创建对象方法
方法 | 说明 |
---|---|
public BigInteger(int num,Random rnd) | 获取随机大整数,范围:[0~2的num次方-1] |
public BigInteger(String val) | 获取指定的大整数 |
public BigInteger(String val,int radix) | 获取指定进制的大整数 |
public static BigInteger valueOf(long val) | 静态方法获取BigInteger对象,内部有优化 |
对象一旦创建,内部记录的值不能改变
- 创建对象方法一:
import java.math.BigInteger;
import java.util.Random;
public class test {
public static void main(String[] args) {
BigInteger bi1=new BigInteger(4,new Random()); //[0,15]
//或者...
Random r=new Random();
BigInteger bi2=new BigInteger(4,r);
}
}
- 创建对象方法二:
import java.math.BigInteger;
import java.util.Random;
public class test {
public static void main(String[] args) {
//传入的字符串必须是整数,否则会报错
BigInteger bi3=new BigInteger("1000000000000000000000000000000000000000000000");
//BigInteger bi3=new BigInteger("10.0");————报错
//BigInteger bi3=new BigInteger("abc");————报错
}
}
- 创建对象方法三:
public class test {
public static void main(String[] args) {
//字符串的数字必须是整数
//字符串中的数字必须与进制吻合,否则报错
BigInteger bi4 = new BigInteger("11", 2);
System.out.println(bi4); //3
}
}
- 创建对象方法四:
package test14;
import java.math.BigInteger;
import java.util.Random;
public class test {
public static void main(String[] args) {
//能表示的范围比较小,只能在long范围以内的整数,超过范围则报错
//在内部对常用数字 -16~16 进行优化:
//先创建好 -16~16 BigInteger的对象,多次获取不会创建新的对象
BigInteger bi5 = BigInteger.valueOf(988888888888888888L);
System.out.println(bi5); //988888888888888888
BigInteger bi6 = BigInteger.valueOf(16);
BigInteger bi7 = BigInteger.valueOf(16);
System.out.println(bi6 == bi7); //true
BigInteger bi8 = BigInteger.valueOf(17);
BigInteger bi9 = BigInteger.valueOf(17);
System.out.println(bi8 == bi9); //false
}
}
- 两个BigInteger相加:
import java.math.BigInteger;
import java.util.Random;
public class test {
public static void main(String[] args) {
BigInteger bi8 = BigInteger.valueOf(17);
BigInteger bi9 = BigInteger.valueOf(17);
BigInteger bi10=bi8.add(bi9);
System.out.println(bi10); //34
}
}
总结:
1.如果BigInteger表示的数字没有超出long范围,用静态方法valueOf获取
2.如果BigInteger表示的数字超出long范围,用构造方法BigInteger bi=new BigInteger(“”)获取
3.对象一旦创建,BigInteger内部记录的值不能发生改变
4.只要是计算都会产生一个新的BigInteger对象
1.7.2 BigInteger常见成员方法
方法 | 说明 |
---|---|
public BigInteger add(BigInteger val) | 加法 |
public BigInteger subtract(BigInteger val) | 减法 |
public BigInteger multiply(BigInteger val) | 乘法 |
public BigInteger divide(BigInteger val) | 除法,获取商 |
public BigInteger remainder(BigInteger val) | 获取余数 |
public BigInteger[] divideAndRemainder(BigInteger val) | 除法,获取数组:商是初始元素,余数是最终元素 |
public BigInteger pow(int exponent) | 次幂 |
public BigInteger gcd(BigInteger val) | 返回二者的最大公约数 |
public BigInteger abs() | 绝对值 |
public BigInteger negate() | 负数 |
public BigInteger mod(BigInteger m) | 返回其值为 (this mod m) 的 BigInteger,此方法不同于 remainder,因为它始终返回一个非负BigInteger |
public boolean equals(Object x) | 比较是否相同 |
public BigInteger min(BigInteger val) | 最小值 |
public BigInteger max(BigInteger val) | 最大值 |
public int intValue() | 将此 BigInteger转换为int,超出范围数据有误 |
public long longValue() | 将此 BigInteger 转换为 long,超出范围数据有误 |
public double doubleValue() | 将此 BigInteger 转换为 double,太大精度丢失 |
注意:
如果此 BigInteger 太长而不适合用 int 表示,则仅返回 32 位的低位字节。
注意,此转换会丢失关于该 BigInteger 值的总大小的信息,并返回带有相反符号的结果。