跟着黑马的Java学习视频学者本篇常用的API
一、Math
public static int abs(int a) {
return (a < 0) ? -a : a;
}
public static double ceil(double a) {
return StrictMath.ceil(a);
}
public static double floor(double a) {
return StrictMath.floor(a);
}
public static double pow(double a, double b) {
return StrictMath.pow(a, b);
// default impl. delegates to StrictMath}
}
public static int max ( int a, int b){
return (a >= b) ? a : b;
}
二、System
(1)虚拟机停止 System.exit(0);
System.out.println("hello1");
System.exit(0);
System.out.println("hello2");
(2) 返回当前系统的时间毫秒值形式 public static long currentTimeMillis()
public class TestCurrentTimeMillis {
public static void main(String[] args) {
long start1 = System.currentTimeMillis();
for (int i = 2; i < 10000; i++) {
if (isPrimer1(i)) {
System.out.println(i);
}
}
long end1 = System.currentTimeMillis();
System.out.println("isPrimer1 execution time: " + (end1 - start1) + "ms");
long start2 = System.currentTimeMillis();
for (int i = 2; i < 10000; i++) {
if (isPrimer2(i)) {
System.out.println(i);
}
}
long end2 = System.currentTimeMillis();
System.out.println("isPrimer2 execution time: " + (end2 - start2) + "ms");
}
// 判断一个数是否为质数(未优化)
public static boolean isPrimer1(int number) {
if (number <= 1) return false;
for (int i = 2; i < number; i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
// 判断一个数是否为质数(优化,只需检查到其平方根)
public static boolean isPrimer2(int number) {
if (number <= 1) return false;
for (int i = 2; i <= Math.sqrt(number); i++) {
if (number % i == 0) {
return false;
}
}
return true;
}
}
(3)System.arraycopy方法进行数组拷贝
对于基本数据类型数组(如int[]):
int[] arr1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int[] arr2 = new int[10];
System.arraycopy(arr1, 0, arr2, 4, 3);
对于引用数据类型数组(这里假设有一个父类Person和子类Student的关系):
Student s1 = new Student("张三", 23);
Student s2 = new Student("李四", 24);
Student s3 = new Student("王五", 25);
Student[] brr1 = {s1, s2, s3};
Person[] brr2 = new Person[3];
System.arraycopy(brr1, 0, brr2, 0, 3);
for (int i = 0; i < brr2.length; i++) {
// 强转如果数据源数组和目的地数组都是引用数据类型,那么子类类型可以赋值给父类类型
Student stu=(Student) brr2[i];
System.out.println(stu.getName() + " " + stu.getAge());
}
三、Object是顶级父类,只有无参构造
/*object是顶级父类,只有无参构造*/
public class APi_03Object {
public static void main(String[] args) {
// Student类的实例化和equals()方法使用部分已注释掉
String str = "abc";
StringBuilder sb = new StringBuilder("abc");
// 比较String对象和StringBuilder对象的内容是否相等
System.out.println(str.equals(sb.toString())); // true,因为sb.toString()返回"abc"
System.out.println(sb.toString().equals(str)); // true,同样比较的是字符串内容
// 以下两行代码会抛出编译错误,因为StringBuilder的equals()方法不会直接与String比较
// System.out.println(str.equals(sb));
// System.out.println(sb.equals(str));
}
}
(1)默认情况下,因为Object类中的toString方法返回的是地址值
当打印一个对象,想要看到属性值的话,那么就重写toString方法就可以了。需要在重写的方法中,把对象的属性值进行拼接。
(2)equals 判断对象是否相等,默认使用“==”来比较
重写equals()
方法时必须重写hashCode()
方法
是因为在Java中,如果两个对象相等(即equals()
方法返回true
),
它们的哈希码(hash code)必须相等。
如果两个对象的equals()
方法相等但哈希码不相等,
这会导致在使用基于哈希的集合(如HashMap、HashSet)时出现问题。
因此,为了保持一致性,必须同时重写这两个方法。
四、Clone
把A对象的属性值完全拷贝给B对象,
也叫对象拷贝,对象复制
基本数据类型: 存储的是真实的值
引用数据类型: 存储的是另一个空间的地址值
(1)浅克隆
不管对象内部的属性是基本数据类型还是引用数据类型,都完全拷贝过来
public static void main(String[] args) {
int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
User u1 = new User(1, "张三", "123", "CC", data);
User u2 = (User) u1.clone();
System.out.println(u1.arrToString());
System.out.println(u2.arrToString());
// 验证浅克隆
int[] arr = u1.getData();
arr[0] = 100;
System.out.println(u1.arrToString());
System.out.println(u2.arrToString());
}
(2)深克隆
基本数据类型拷贝过来字符串复用引用数据类型会重新创建新的
@Override
protected Object clone() throws CloneNotSupportedException {
// 先把克隆对象中的数组获取出来
int[] data = this.data;
// 创建新的数组
int[] newdata = new int[data.length];
for (int i = 0; i < data.length; i++) {
newdata[i] = data[i];
}
User u = (User) super.clone();
u.data = newdata;
return u;
}
public static void main(String[] args) {
int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
User u1 = new User(1, "张三", "123", "CC", data);
User u2 = (User) u1.clone();
System.out.println(u1.arrToString());
System.out.println(u2.arrToString());
// 验证浅克隆
int[] arr = u1.getData();
arr[0] = 100;
System.out.println(u1.arrToString());
System.out.println(u2.arrToString());
}
(3)深克隆 – Gson
import com.google.gson.Gson;
public class Main {
public static void main(String[] args) {
// 创建一个Gson对象
Gson gson = new Gson();
// 将Java对象转换为JSON字符串
String json = gson.toJson(new YourObject());
// 将JSON字符串转换为Java对象
YourObject obj = gson.fromJson(json, YourObject.class);
}
// 定义一个示例Java对象
static class YourObject {
String name;
int age;
public YourObject() {
this.name = "Alice";
this.age = 30;
}
}
}
五、Objects
在Java中,Objects类是一个实用类,提供了一些静态方法来操作对象。它包含方法如equals(), hash(), isNull()等。您可以使用这些方法来执行对象的比较、哈希计算和空检查等操作。
如果没有重写,比较地址值,如果重写了,就比较属性值。
// 示例代码
Object obj1 = new Object();
Object obj2 = new Object();
// 使用Objects类的equals方法比较两个对象是否相等
boolean isEqual = Objects.equals(obj1, obj2);
// 使用Objects类的hash方法计算对象的哈希值
int hashValue = Objects.hash(obj1, obj2);
// 使用Objects类的isNull方法检查对象是否为null
boolean isNull = Objects.isNull(obj1);
六、精确的数(Biginteger、BigDecima)
6.1 BigInteger
对象一旦创建,内部记录的值就不能再发生改变
构造方法
通过指定基数和字符串值构造:
BigInteger(String value, int radix)
通过字符串值构造
BigInteger(String value)
获取随机大整数,范围: [0 ~ 2的num次方-1]
public BigInteger(int num, Random rnd)
BigInteger.valueOf(long val)
是一个静态方法,用于创建一个包含指定 long 值的 BigInteger
实例。这个方法可以方便地将基本数据类型转换为 BigInteger
对象。
6.1.1 静态方法
BigInteger
类中的静态方法valueOf(long val)
可以接受long
类型的值作为参数,该值的范围在-2^63
到2^63-1
之间。如果超出这个范围,可以使用BigInteger
的构造函数来处理更大范围的整数。
在内部对于常用的数字-16~16进行了优化,先行创建好的,多次获取的不会重新创建新的。
对象一旦创建内部数据不能发生改变
6.1.2 BigInteger
构造方法小结
- 静态方法获取:如果
BigInteger
表示的数字没有超出long
的范围,可以用静态方法获取。 - 构造方法获取:如果
BigInteger
表示的数字超出long
的范围,可以用构造方法获取。 - 不可变性:对象一旦创建,
BigInteger
内部记录的值不能发生改变。 - 新对象生成:只要进行计算都会产生一个新的
BigInteger
对象。
6.1.3 常见方法
public BigInteger add(BigInteger val); // 返回两个 BigInteger 的和
public BigInteger subtract(BigInteger val); // 返回两个 BigInteger 的差
public BigInteger multiply(BigInteger val); // 返回两个 BigInteger 的乘积
public BigInteger divide(BigInteger val); // 返回两个 BigInteger 的商
public BigInteger mod(BigInteger val); // 返回两个 BigInteger 除法的余数
public BigInteger[] divideAndRemainder(BigInteger val) //商、余数
public BigInteger pow(int exponent); // 返回 BigInteger 的指数次幂
public BigInteger abs(); // 返回 BigInteger 的绝对值
public BigInteger negate(); // 返回 BigInteger 的负值
public int compareTo(BigInteger val); // 比较两个 BigInteger 的大小
public BigInteger max(BigInteger val); // 返回两个 BigInteger 中的最大值
public BigInteger min(BigInteger val); // 返回两个 BigInteger 中的最小值
public BigInteger and(BigInteger val); // 进行位与运算
public BigInteger or(BigInteger val); // 进行位或运算
public BigInteger xor(BigInteger val); // 进行位异或运算
public BigInteger not(); // 进行位非运算
public BigInteger shiftLeft(int n); // 进行左移位运算
public BigInteger shiftRight(int n); // 进行右移位运算
public int intValue(); // 将 BigInteger 转换为 int 类型
public long longValue(); // 将 BigInteger 转换为 long 类型
public float floatValue(); // 将 BigInteger 转换为 float 类型
public double doubleValue(); // 将 BigInteger 转换为 double 类型
例
// 创建两个 BigInteger 实例
BigInteger num1 = new BigInteger("3");
BigInteger num2 = new BigInteger("2");
// 加法
BigInteger sum = num1.add(num2);
System.out.println("加法结果: " + sum);
// 减法
BigInteger difference = num1.subtract(num2);
System.out.println("减法结果: " + difference);
// 乘法
BigInteger product = num1.multiply(num2);
System.out.println("乘法结果: " + product);
// 除法
BigInteger quotient = num1.divide(num2);
System.out.println("除法结果: " + quotient);
6.1.4 原理
Java中的BigInteger
类是用于表示任意精度整数的类。它的底层原理是使用数组来存储大整数的各个部分,并提供了相应的方法来执行整数运算,如加法、减法、乘法和除法。BigInteger
类允许处理比基本整数类型更大范围的整数值,因为它不受固定位数限制。
6.2 BigDecima不可变的,任意精度有符号计算的十进制数
BigDecimal是Java中用于高精度计算的类,它提供了任意精度的浮点数运算。与基本数据类型如double或float不同,BigDecimal可以准确表示浮点数运算,避免了传统浮点数运算中的精度丢失问题。
6.2.1 构造方法
-
通过字符串构造:
BigDecimal(String val)
- 通过字符串形式的数字创建一个BigDecimal对象。–没有不可预知性。 -
通过整型构造:
BigDecimal(int val)
- 通过整型值创建一个BigDecimal对象。 -
通过双精度浮点数构造:
BigDecimal(double val)
- 通过双精度浮点数创建一个BigDecimal对象。—有些不接预知性
这些构造方法允许您以不同的方式初始化BigDecimal对象,根据您的需求选择合适的构造方法。
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
String numberStr = "123.456";
BigDecimal bigDecimal = new BigDecimal(numberStr);
System.out.println("BigDecimal value: " + bigDecimal);
}
}
- 如果表示的数字不大,没有超出
double
的取值范围,建议使用静态方法valueOf
。 - 如果表示的数字比较大,超出了
double
的取值范围,建议使用构造方法。 - 如果传递的是0到10之间的整数(包括0和10),
valueOf
方法会返回已经创建好的对象,不会重新创建新的对象。
6.2.2 静态方法
BigDecimal类的静态方法valueOf
允许您通过传入基本数据类型值来创建一个BigDecimal对象。这个方法有几种重载形式,其中一种常见的是valueOf(long val)
,它接受一个长整型值作为参数并返回对应的BigDecimal对象。这种方法提供了一种方便的方式来将基本数据类型转换为BigDecimal对象。
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
long longValue = 1000L;
BigDecimal bigDecimal = BigDecimal.valueOf(longValue);
System.out.println("BigDecimal value: " + bigDecimal);
}
}
6.2.3 常用方法
1. `add(BigDecimal val)` - 将当前BigDecimal对象与另一个BigDecimal对象相加。
2. `subtract(BigDecimal val)` - 从当前BigDecimal对象中减去另一个BigDecimal对象。
3. `multiply(BigDecimal val)` - 将当前BigDecimal对象与另一个BigDecimal对象相乘。
4. `divide(BigDecimal val, int scale, RoundingMode roundingMode)` - 将当前BigDecimal对象除以另一个BigDecimal对象,可以指定保留小数位数和舍入方式。
5. `compareTo(BigDecimal val)` - 将当前BigDecimal对象与另一个BigDecimal对象进行比较。
例子
BigDecimal num1 = new BigDecimal("10.5");
BigDecimal num2 = new BigDecimal("5.2");
// Addition
BigDecimal sum = num1.add(num2);
System.out.println("Sum: " + sum);
// Subtraction
BigDecimal difference = num1.subtract(num2);
System.out.println("Difference: " + difference);
// Multiplication
BigDecimal product = num1.multiply(num2);
System.out.println("Product: " + product);
// Division
BigDecimal quotient = num1.divide(num2, 2, RoundingMode.HALF_UP);
System.out.println("Quotient: " + quotient);
// Comparison
int comparison = num1.compareTo(num2);
System.out.println("Comparison result: " + comparison);
6.2.4 常见的舍入方式
-
RoundingMode.UP
- 向远离零的方向舍入,即向正无穷大方向舍入。 -
RoundingMode.DOWN
- 向零的方向舍入,即截断小数部分。 -
RoundingMode.CEILING
- 向正无穷大方向舍入,如果为负数则向零方向舍入。 -
RoundingMode.FLOOR
- 向负无穷大方向舍入,如果为负数则向负无穷大方向舍入。 -
RoundingMode.HALF_UP
- 四舍五入,当小数部分大于等于0.5时向正无穷大方向舍入。 -
RoundingMode.HALF_DOWN
- 四舍五入,当小数部分大于0.5时向正无穷大方向舍入。 -
RoundingMode.HALF_EVEN
- 银行家舍入规则,当小数部分为0.5时,向最接近的偶数方向舍入。
这些舍入方式可以根据需要选择,以控制小数部分的舍入行为。
6.2.5 底层原理
BigDecimal类的底层原理涉及使用BigInteger来表示整数部分,以及使用int变量来表示小数点的位置和标度。这种设计允许BigDecimal类支持任意精度的小数运算,避免了传统浮点数运算中的精度丢失问题。
当执行加减乘除等运算时,BigDecimal类会根据操作数的标度进行运算,并根据需要调整结果的标度。此外,BigDecimal还提供了控制舍入方式的选项,以确保精确的计算结果。
总的来说,BigDecimal类通过使用整数部分和标度来表示数字,以及提供精确的数学运算和舍入控制,实现了高精度的浮点数计算。