Java常用的API

Math类的常用方法 

abs的bug:


以int类型为例,取值范围:-2147483648~2147483647

如果没有正数与负数对应,那么传递负数结果有误

-2147483648 没有正数与之对应,所以abs结果产生bug

system.out.println(Math.abs(-2147483648));//-2147483648,出现bug
system.out.println(Math.abs(-2147483647));//2147483647 

开根号:

Math.sqrt(4) // 输出2.0,开平方根
Math.cbrt(8) // 输出2.0,开立方根

 random的应用:

// 输出1~100的随机数
System.out.println(Math.floor(Math.random()*100 + 1));

System:

System也是一个工具类,提供了一些与系统相关的方法。

 

 // 需要把整个程序结束的时候
        System.exit(0);

        // 获取程序运行的总时间
        long l = System.currentTimeMillis(); // 单位毫秒
        System.out.println(l);

        int[] arr1 = {1,2,3,4,5,6,7,8,9,10};
        int[] arr2 = new int [10];
        // 把arr1的数组拷贝到arr2中
        // 参数一:数据源,要拷贝的数据要从哪个数组而来
        // 参数二:从数据源数组中的第几个索引开始拷贝
        // 目的地,我把数据拷贝到哪个数组
        //目的地数组的索引
        // 拷贝的个数
        System.arraycopy(arr1, 0, arr2, 0, arr1.length);
        //   细节:
        // 如果数据源数组和目的地数组都是基本数据类型,那么两者的类型必须保持一致,否则会出错
        // 在拷贝的时候需要考虑数组的长度。如果超出范围则会报错
        // 如果数组源数组和目的地数组都是引用数据类型(地址值),那么子类类型可以复制给父类类型

Runtime:

// 获取Runtime的对象
        // 由于底层代码让构造方法私有化,所以外界不准创建Runtime的对象
        Runtime r1 = Runtime.getRuntime();

        // exit停止虚拟机
        Runtime.getRuntime().exit(0);

        // 获取CPU的线程数
        System.out.println(Runtime.getRuntime().availableProcessors()); // 12(不一定)

        // 总内存大小,单位byte字节
        System.out.println(Runtime.getRuntime().maxMemory());

        // 已经获取的总内存大小,单位byte字节
        System.out.println(Runtime.getRuntime().totalMemory());

        // 剩余内存的大小
        System.out.println(Runtime.getRuntime().freeMemory());

        // 运行cmd命令
        // shutdown 关机
        // 加上参数才能执行
        //-s:默认在1min后关机
        //-s -t     指定时间:指定关机时间
        //-a:取消关机操作
        //-r:关机并重启

        Runtime.getRuntime().exec("notepad");
        Runtime.getRuntime().exec("shutdown -a");

object:

object是Java中的顶级父类。所有的类都直接或间接的继承于object类。
object类中的方法可以被所有子类访问,所以我们要学习object类和其中的方法。

 public boolean equals(Object obj)

  • 作用:用于比较两个对象是否“相等”。默认实现是比较两个对象的引用是否相同,即判断它们是否指向同一个内存地址。

  • 重写:通常会重写equals方法,以提供对象内容的比较。例如,比较两个Person对象时,可能需要比较它们的姓名和年龄,而不仅仅是内存地址。 (在类里面重写)

结论:
如果没有重写equals方法,那么默认使用object中的方法进行比较,比较的是地址值是否相等

一般来讲地址值对于我们意义不大,所以我们会重写,重写之后比较的就是对象内部的属性值了。

// 比较对象内部的属性值
@Override
public boolean equals(Object obj) {
    if (this == obj) return true;// 判断是不是同一个对象
    if (obj == null || getClass() != obj.getClass()) return false; // 非空判断和类是否相同
    Person person = (Person) obj;
    return age == person.age && Objects.equals(name, person.name);
}

例子: 

 public String toString()

  • 作用:返回对象的字符串表示,默认实现是返回对象的类名+@+哈希码的十六进制值。

  • 重写:通常会重写toString方法,以提供对象的详细信息,例如字段值的字符串表示。

思考:默认情况下,因为object类中的tostring方法返回的是地址值。所以,默认情况下,打印一个对象打印的就是地址值,但是地址值对于我们是没什么意义的。

我想要看到对象内部的属性值?我们该怎么办?

处理方案:重写父类0bject类中的tostring方法 

@Override
public String toString() {
    return "Person{name='" + name + "', age=" + age + '}';
}

clone方法:

1. clone() 方法的基本概念
  • 定义clone() 方法用于创建并返回当前对象的一个副本。这个副本通常被称为“克隆对象”。

  • 声明clone() 方法在 Object 类中是 protected 访问级别,这意味着只有在子类中可以直接访问它,或者通过重写并改变其访问级别为 public 才能在外部调用。

  • 抛出异常:该方法可能会抛出 CloneNotSupportedException 异常,这是因为并非所有对象都可以被克隆。为了让一个对象能够被克隆,它的类必须实现 Cloneable 接口,否则调用 clone() 方法时将抛出此异常。

@Override
protected Object clone() throws CloneNotSupportedException {
    return super.clone();
}
2. Cloneable 接口
  • 功能Cloneable 是一个标识接口(即没有任何方法),用于指示该类的对象可以安全地使用 clone() 方法进行克隆。如果一个类没有实现 Cloneable 接口,调用 clone() 方法时会抛出 CloneNotSupportedException

  • 作用:实现 Cloneable 接口的类表明它同意并且支持使用 clone() 方法进行对象的克隆操作。

public class Person implements Cloneable {
    private String name;
    private int age;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
3. 浅拷贝与深拷贝
  • 浅拷贝object 类的默认 clone() 方法执行的是浅拷贝,即复制当前对象及其所有字段的副本,但如果这些字段是对象的引用,浅拷贝只复制引用,而不复制引用对象本身。这意味着原对象和克隆对象共享引用类型字段的数据。

例子:如果一个对象有一个数组或其他对象作为字段,浅拷贝只会复制数组的引用,而不会复制数组的内容。

class Person implements Cloneable {
    String name;
    int[] data;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();  // 浅拷贝
    }
}

public class TestClone {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person();
        p1.name = "Alice";
        p1.data = new int[]{1, 2, 3};

        Person p2 = (Person) p1.clone();
// == 对于引用型数据则比较内存地址,Object 类的默认 equals() 实现也是比较内存地址
        System.out.println(p1.name.equals(p2.name)); // true
        System.out.println(p1.data == p2.data);      // true, data 数组共享,指向的是同一个数组

    }
}

深拷贝:深拷贝不仅复制对象本身,还会递归复制所有引用类型字段指向的对象。这意味着克隆后的对象与原对象完全独立,它们不共享任何引用类型字段。

实现方式:要实现深拷贝,必须在重写 clone() 方法时手动复制所有引用类型字段的内容。通常需要逐层调用 clone() 方法,或者创建这些引用对象的新实例。

class Person implements Cloneable {
    String name;
    int[] data;

// 深浅拷贝结合
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();  // 浅拷贝
        cloned.data = this.data.clone();         // 深拷贝
        return cloned;
    }
}

public class TestClone {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person();
        p1.name = "Alice";
        p1.data = new int[]{1, 2, 3};

        Person p2 = (Person) p1.clone();

        System.out.println(p1.name.equals(p2.name)); // true
        System.out.println(p1.data == p2.data);      // false, data 数组被深拷贝,在内存中开辟了新的地址
    }
}

 objects工具类:

1. objects.equals(Object a, Object b)

  • 功能:安全地比较两个对象是否相等。如果两个对象都是 null,则返回 true;如果只有一个对象是 null,则返回 false;否则,调用 a.equals(b) 进行比较。

  • 好处:避免了手动检查 null 值的麻烦,减少了 NullPointerException 的风险。

String s1 = null;
String s2 = "hello";

System.out.println(Objects.equals(s1, s2));  // 输出: false
System.out.println(Objects.equals(s1, null)); // 输出: true

2. Objects.isNull(Object obj)

  • 功能:判断对象是否为 null。该方法的作用相当于 obj == null

  • 好处:使代码更加语义化,更加可读。

3. Objects.nonNull(Object obj)

  • 功能:判断对象是否非 null。该方法相当于 obj != null

  • 好处:语义化表达,通常用于流操作中进行 null 过滤。

BigInteger:

. BigInteger 的基本特性

  • 不可变性BigInteger 对象是不可变的。一旦创建,它的值就不能被更改。每次进行操作时,都会返回一个新的 BigInteger 对象。

  • 任意精度BigInteger 可以表示的整数大小仅受限于可用的内存,因此可以处理非常大的整数。

2. 创建 BigInteger 对象

可以通过以下几种方式创建 BigInteger 对象:

  • 通过字符串创建:这是最常用的方式,可以从任意长度的字符串创建一个 BigInteger

BigInteger bigInt = new BigInteger("123456789012345678901234567890");

通过基本类型创建:可以使用 valueOf 方法从基本类型(如 long)创建一个 BigInteger

BigInteger bigInt = BigInteger.valueOf(123456789L);

 场景:当你有一个非常大的整数,它超出了 long 的范围(超过 9223372036854775807),或者该数值是以字符串形式存储时,可以使用字符串来创建 BigInteger

BigInteger.valueOf(long value) 在内部会缓存 -1616 之间的 BigInteger 对象,这样在这些范围内的数字每次调用时不会创建新的 BigInteger 对象,而是直接返回缓存中的实例。

BigInteger a = BigInteger.valueOf(10);
BigInteger b = BigInteger.valueOf(10);

System.out.println(a == b);  // 输出: true
System.out.println(a.equals(b));  // 输出: true

BigInteger c = BigInteger.valueOf(100);
BigInteger d = BigInteger.valueOf(100);

System.out.println(c == d);  // 输出: false
System.out.println(c.equals(d));  // 输出: true

3. BigInteger 的运算

BigInteger 提供了类似于基本数据类型的数学运算方法,包括加法、减法、乘法、除法、取模等。由于 BigInteger 是不可变的,每次操作都会返回一个新的对象

  • 加法:

    BigInteger a = new BigInteger("123456789"); BigInteger b = new BigInteger("987654321"); 
    BigInteger sum = a.add(b);
  • 减法

    BigInteger difference = a.subtract(b);
  • 乘法

    BigInteger product = a.multiply(b);
  • 除法

    BigInteger quotient = a.divide(b);
  • 取模

    BigInteger mod = a.mod(b);
  • 幂运算

BigInteger power = a.pow(10); // 计算 a 的 10 次幂
  • 最大公约数(GCD)

    BigInteger gcd = a.gcd(b); // 计算 a 和 b 的最大公约数
  • 取反运算

    BigInteger negation = a.negate(); // 返回 a 的相反数
  • 绝对值

    BigInteger absValue = a.abs(); // 返回 a 的绝对值
  • 求模的同时求商

    BigInteger[] result = a.divideAndRemainder(b); 
    BigInteger quotient = result[0]; // 商 
    BigInteger remainder = result[1]; // 余数
  • 模幂运算:常用于加密算法中,可以高效计算 (base^exponent) % modulus

    BigInteger modPow = a.modPow(b, m); // 计算 (a^b) % m
    

    4. BigInteger 的比较方法

相等比较:使用 equals() 方法判断两个 BigInteger 对象的数值是否相等。boolean isEqual = a.equals(b);

总结:

BigDecimal:

计算机的小数:

BigDecimal 是 Java 中用于高精度浮点数计算的类,位于 java.math 包中。

1. BigDecimal 的基本特性

  • 不可变性BigDecimal 对象是不可变的。一旦创建,它的值就不能被更改。每次进行操作时,都会返回一个新的 BigDecimal 对象。

  • 任意精度BigDecimal 可以表示非常大或非常小的数值,并且可以精确到小数点后的任意位数。

2. 创建 BigDecimal 对象

可以通过以下几种方式创建 BigDecimal 对象:

  • 通过字符串创建:这是推荐的方式,因为它能避免由于浮点数转换带来的精度问题。

    BigDecimal bigDecimal = new BigDecimal("123.456");
  • 通过基本类型创建:可以通过 intlongdouble 等类型直接创建 BigDecimal,但注意使用 double 可能会引入精度问题。

    BigDecimal fromInt = new BigDecimal(123); 
    BigDecimal fromLong = new BigDecimal(123L); 
    BigDecimal fromDouble = new BigDecimal(123.456); // 不推荐,会失去精度

    注意:建议避免使用 BigDecimal(double) 构造函数,因为 double 可能会丢失精度。使用 BigDecimal.valueOf(double) 是更好的选择。

    BigDecimal safeFromDouble = BigDecimal.valueOf(123.456);

细节:
1.如果要表示的数字不大,没有超出double的取值范围,建议使用静态方法

2.如果要表示的数字比较大,超出了double的取值范围,建议使用字符串的构造方法

3.如果我们传递的是0~10之问的整数,包含0,包含10,那么方法会返回己经创建好的对象,不会重新new,如果是double类型的还是会重新new。

3. BigDecimal 的基本运算

BigDecimal 提供了类似于 BigInteger 的基本数学运算方法,包括加法、减法、乘法、除法、取模等。所有这些方法都会返回一个新的 BigDecimal 对象。

  • 加法

    BigDecimal a = new BigDecimal("123.45"); 
    BigDecimal b = new BigDecimal("678.90"); 
    BigDecimal sum = a.add(b);
  • 减法

    BigDecimal difference = a.subtract(b);
  • 乘法

    BigDecimal product = a.multiply(b);
  • 除法

    BigDecimal quotient = a.divide(b, RoundingMode.HALF_UP); // 指定舍入模式

    注意:除法操作必须指定舍入模式,否则可能抛出 ArithmeticException,因为 BigDecimal 不一定能精确除尽。

4. BigDecimal 的舍入模式

  • RoundingMode.UP:向远离零的方向舍入。
  • RoundingMode.DOWN:向接近零的方向舍入。
  • RoundingMode.CEILING:向正无限大方向舍入。
  • RoundingMode.FLOOR:向负无限大方向舍入。
  • RoundingMode.HALF_UP:四舍五入,如果离中间值等距,向上舍入。
  • RoundingMode.HALF_DOWN:五舍六入,如果离中间值等距,向下舍入。
  • RoundingMode.HALF_EVEN:银行家舍入法,如果离中间值等距,舍入到偶数。

底层储存方式: 

总结:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值