2023年12月24日06:54:24 备赛期间:通宵早上写的该博客!
Java进阶(第五期)
一、Object类
1.1 关 toString()方法
1.1.2 代码示例
package com.liujintao.object.tostring;
public class ToStringDemo {
public static void main(String[] LiuJinTao) {
// 经过重写toString方法
Student stu = new Student("张三", 23);
System.out.println(stu.toString()); // 张三 --- 23
System.out.println(stu); // 张三 --- 23
// 没有经过重写toString方法
ClassDemo cd = new ClassDemo();
System.out.println(cd.toString());
System.out.println(cd);
/*
打印过的结果如下:(分析 toString()看看如下的结果)
com.liujintao.object.tostring.ClassDemo@14ae5a5
com.liujintao.object.tostring.ClassDemo@14ae5a5
*/
}
}
// 声明了一个成员内部类
class ClassDemo {
public String name;
public int age;
public void show () {
System.out.println("所有类默认继承了Object类,自然就会共享到里面的方法");
}
}
- 下面是一个Student类
package com.liujintao.object.tostring;
public class Student {
private String name;
private int age;
// 重写 toString方法
@Override
public String toString() {
// return super.toString(); 我重写就是为了不需要父类的东西,所以这里注释掉
// 我只需要对象调用了 toString方法,直接返回指定的东西(例如这里返回姓名和年龄)
return name + " --- " + age;
}
-
好处就是你可以使用toString看到类中的属性值,不单单只看见全类名的哈希值。
-
可以使用在JavaBean中使用toString方法。
-
当我们打印一个类对象或者引用看到的是内容而不是地址值,那么他本类或者父类一定进行了toString()方法的重写!
1.2 equals()方法
1.2.2 代码示例
package com.liujintao.object.mequals;
import java.util.ArrayList;
public class EqualsDemo {
public static void main(String[] LiuJinTao) {
Student stu1 = new Student("张三", 23);
Student stu2 = new Student("张三", 23);
System.out.println(stu1.equals(stu2)); // true
ArrayList<String> list = new ArrayList<String>();
System.out.println(stu1.equals(list)); // false
}
}
Student类代码:
- 自己写的equals方法类
package com.liujintao.object.mequals;
public class Student {
private String name;
private int age;
// 这里自己重写 equals方法
@Override
public boolean equals (Object obj) {
if (obj instanceof Student) {
// Object是父类,声明了一个obj引用,等待子类对象(多态)
Student stu = (Student) obj; // 向下强制转型解决多态父类引用无法访问子类特有成员
return this.age == stu.age && this.name.equals(stu.name);
} else {
return false;
}
}
-
主要是自己重写比较规则。因为默认比较的还是地址。
-
idea生成的equals方法
// idea生成 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);
}
1.3 Objects 常见方法
1.3.1 Objects.equals方法
- 问题:Objects.equals方法, 和 stu1.equals方法,有什么区别?
- 细节:Objects.equals方法, 内部依赖于我们自己编写的equals,也就是说,访问不到自己写的,就会使用默认的,比较地址值是否相等,。
- 好处:Objects.equals方法, 内部带有非 null 判断。
System.out.println(Objects.equals(stu1, stu2));
System.out.println("我应该会执行吗?")
- 如果我们重写了且,stu1 和 stu2 值确实相等,那么返回true,反之false,且会执行下面的语句。
- 如果没重写,地址不相等,返回false 且不会执行语句下面的代码。
(是否会执行下面的语句,取决于是否会爆出空指针异常),非空判断就可以跳过报错!
1.3.2 Objects源码分析
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
1.4 isNull方法
- 该方法就和 对象 == null 用法一样
二、Math 类
package com.liujintao.math;
public class MathDemo {
public static void main (String[] LiuJinTao) {
System.out.println(Math.abs(-123)); // 123
System.out.println(Math.abs(-12.3)); // 12.3
System.out.println("--------------------------");
System.out.println(Math.ceil(12.0)); // 12.0
System.out.println(Math.ceil(12.2)); // 13
System.out.println(Math.ceil(12.5)); // 13
System.out.println(Math.ceil(12.9)); // 13
System.out.println("--------------------------");
System.out.println(Math.floor(12.0)); // 12.0
System.out.println(Math.floor(12.2)); // 12.0
System.out.println(Math.floor(12.5)); // 12.0
System.out.println(Math.floor(12.9)); // 12.0
System.out.println("--------------------------");
System.out.println(Math.round(3.4)); // 3
System.out.println(Math.round(3.6)); // 4
System.out.println("--------------------------");
System.out.println(Math.max(10, 20)); // 20
System.out.println(Math.min(10, 20)); // 10
System.out.println("--------------------------");
System.out.println(Math.pow(2, 3)); // 8.0
System.out.println("--------------------------");
System.out.println(Math.random()); // 0.0 - 1.0(不包含)之间的随机数
}
}
三、System类
3.1 System概述
3.2 代码示例
- 时间戳:
System.currentTimeMillis();
package com.liujintao.system;
public class SystemDemo {
public static void main(String[] LiuJinTao) {
// 通过时间戳来计算一个程序执行所消耗的时间
long start = System.currentTimeMillis();
for (int i = 1; i < 100000; i++) {
String s = "";
s += i;
System.out.print(s);
}
long end = System.currentTimeMillis();
System.out.println(end - start + "ms"); // 240 ms
}
}
- 数组拷贝:
System.arraycopy(原数组, 拷贝起始值, 新数组,粘贴起始值, 拷贝长度);
int [] arr = {11, 22, 33, 44, 55};
int [] newArr = new int [3];
System.arraycopy(arr, 2, newArr, 0, 3);
for (int i : newArr) {
System.out.println(i); // 33 44 55
}
四、BigeDecimal类
BigDecimal 可以实现对浮点数的运算,不会造成精度丢失。
通常情况下,大部分需要浮点数精确运算结果的业务场景(比如涉及到钱的场景)都是通过 BigDecimal 来做的。
1、第一种方法(不推荐使用):传递一个 double类型
// 传递double类型
BigDecimal bd1 = new BigDecimal(0.2);
BigDecimal bd2 = new BigDecimal(0.3);
System.out.println(bd1.add(bd2)); // .500000000000000000000000000000000000000000000000000000
2、第二种方法:传递一个 String 类型
(推荐使用)
// 传递String类型
BigDecimal bd1 = new BigDecimal("0.2");
BigDecimal bd2 = new BigDecimal("0.3");
System.out.println(bd1.add(bd2)); // 0.5
3、第三种方法:调用 valueOf 方法
(推荐使用)
// 调用 valueOf方法
BigDecimal bd1 = BigDecimal.valueOf(0.2);
BigDecimal bd2 = BigDecimal.valueOf(0.2);
System.out.println(bd1.add(bd2)); // 0.4
4、方法汇总:(加、减、乘、除)
BigDecimal bd1 = BigDecimal.valueOf(10);
BigDecimal bd2 = BigDecimal.valueOf(3);
System.out.println(bd1.add(bd2)); // 13
System.out.println(bd1.subtract(bd2)); // 7
System.out.println(bd1.multiply(bd2)); // 30
System.out.println(bd1.divide(bd2, 2,
- 除法细节
RoundingMode.HALF_UP)); // 3.33 四舍五入
System.out.println(bd1.divide(bd2, 2, RoundingMode.UP)); // 3.34 向上取整
System.out.println(bd1.divide(bd2, 2, RoundingMode.DOWN)); // 3.33 向下取整
6、数据转换为 double 处理(doubleValue())
BigDecimal result = bd1.divide(bd2,2, RoundingMode.HALF_UP); // 用变量接收计算后的结果
double v = result.doubleValue(); // 将 BigDecimal类型转为 double类型
System.out.println(Math.abs(v)); // 对处理后的记过进行取绝对值操作
五、包装类
- 将基本数据类型包装成引用数据类型
5.1 手动和自动装箱、拆箱 (Integer)
-
基本数据类型,和对应的包装类,可以直接做运算,不需要我们自己手动转换了。
-
JDK 5 后,我们不需要操行上面手动操作了,该版本后,自动拆装箱
5.2 代码示例
package com.liujintao.bigdecimal;
public class IntegerDemo {
public static void main(String[] LiuJinTao) {
// 一、手动拆装箱
System.out.println("---------------------------");
// 1、 通过构造函数手动装箱
int num = 520;
Integer i1 = new Integer(num); // 过时的不必要装箱
// 2、 通过静态方法手动装箱
Integer i2 = Integer.valueOf(num);
System.out.println("---------------------------");
// 通过 intValue() 手动拆箱
int num2 = i1.intValue(); // 过时的不必要拆箱
System.out.println(num2); // 520
// 二、自动拆装箱
System.out.println("---------------------------");
// JDK 5 后,我们不需要操行上面手动操作了,该版本后,自动拆装箱
int num3 = 1314;
Integer i3 = num3; // 自动装箱
int num4 = i3; // 自动拆箱
System.out.println(num4); // 1314
System.out.println("---------------------------");
}
}
5.3 包装类常用方法
// 包装类中的方法示例
int n = 100;
String str = "100";
System.out.println(Integer.toBinaryString(n)); // 01100100
System.out.println(Integer.toOctalString(n)); // 144
System.out.println(Integer.toHexString(n)); // 64
System.out.println(Integer.parseInt(str) + n); // 200
5.4 包装类练习
需求:已知字符串 String s = “10, 50, 30, 20, 40”;
请将该字符串转换为整数并存入数组
随后求出最大值
- 代码示例:
package com.liujintao.integer;
import org.w3c.dom.ls.LSOutput;
import java.net.SocketTimeoutException;
public class IntegerTest {
public static void main(String[] LiuJinTao) {
String s = "10,50,30,20,40";
String[] strArray = s.split(",");
// 创建一个int类型数组
int [] nums = new int [strArray.length];
int max = nums[0];
// 遍历数组
for (int i = 0; i < strArray.length; i++) {
nums[i] = Integer.parseInt(strArray[i]); // 使用包装类转为整数类型
if (max < nums[i]) {
max = nums[i];
}
}
System.out.println("最大值为:" + max); // 50
System.out.println("-----------------------------------");
}
}
5.5 包装类面试题
package com.liujintao.integer;
public class IntegerTest2 {
public static void main(String[] LiuJinTao) {
// 注意:自动转型,虚拟机会自动帮我们调用 Integer 中的 valueOf()静态方法
// 这里的包装类值在范围内,所以他会取出数组中的数值。这里两个包装类值都一样,访问的数组索引也一样,索引一样,值肯定亦一样,返回true
Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1 == i2); // true
// 显而易见,这里超出了int 包装类的范围,所以堆空间分别创建两个空间,比较地址肯定为false
Integer i3 = 129;
Integer i4 = 129;
System.out.println(i3 == i4); // false
// 源码解析
/*
该方法传入一个范围为 (-127 - 128)
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
*/
}
}
- 数组存放了 256个Integer数组, 只要传入的数符合范围,并且访问的是同一个索引号,那么返回的肯定是true.