常见类整理

46 阅读20分钟

19-常用类

包装类

Untitled.png

Untitled.png Untitled.png

Untitled.png

包装类与基本数据转换

package org.example;

/**
 * @author adekang
 * @version 1.0
 * @date 2023/8/19
 */
public class Integer01 {
    public static void main(String[] args) {
        int n1 = 100;
        Integer integer1 = n1;
    }
}

包装类与String转换

package org.example;

/**
 * @author adekang
 * @version 1.0
 * @date 2023/8/19
 */
public class Integer01 {
    public static void main(String[] args) {
        Integer i = 100;
        //  方式一
        String str1 = i + "";
        //  方式二
        String str2 = i.toString();
        String str3 = String.valueOf(i);

        //      String - > Integer
        String str4 = "123456";
        Integer i2 = Integer.parseInt(str4);
    }
}

常用方法

package org.example;

/**
 * @author adekang
 * @version 1.0
 */
public class WrapperMethod {
    public static void main(String[] args) {
        System.out.println(Integer.MIN_VALUE); //返回最小值
        System.out.println(Integer.MAX_VALUE);//返回最大值

        System.out.println(Character.isDigit('a'));//判断是不是数字
        System.out.println(Character.isLetter('a'));//判断是不是字母
        System.out.println(Character.isUpperCase('a'));//判断是不是大写
        System.out.println(Character.isLowerCase('a'));//判断是不是小写

        System.out.println(Character.isWhitespace('a'));//判断是不是空格
        System.out.println(Character.toUpperCase('a'));//转成大写
        System.out.println(Character.toLowerCase('A'));//转成小写

    }
}

面试题

package org.example;

/**
 * @author adekang
 * @version 1.0
 * @date 2023/8/19
 */
public class Integer01 {
    public static void main(String[] args) {

        //

        // Integer 在 -128~127 是从数组中取值  大于这个范围则是 返回一个包装对象
        Integer i1 = 128;
        Integer i3 = 128;
        System.out.println(i1 == i3);

        //  只要有基本数据类型就判断是否值相同
        int i2 = 128;
        Integer i4 = 128;
        System.out.println(i2 == i4);
    }
}

String

  1. String对象用于保存字符串,也就是一组字符序列
  2. 字符串常量对象是用双引号括起的字符序列。
  3. 字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节。
  4. String类较常用构造器(其它看手册):

Untitled.png String类实现了

接口SeriaLizabLe [String可以串行化:可以在网络传输] 接口Comparable [String 对象可以比较大小]

String是final 类,不能被其他的类继承 String有属性private final char vaLue[]; 用于存放字符串内容 定要注意: value 是一个finaL类型, 不可以修改

创建

package org.example;

/**
 * @author adekang
 * @version 1.0
 * @date 2023/8/19
 */
public class Integer01 {
    public static void main(String[] args) {

        String s = "ade";
        String s2 = new String("ade");

    }
}

方式一:先从常量池查看是否有"ade"数据空间,如果有,直接指向;如果没有则重新创建,然后指向。s最终指向的是常量池的空间地址

方式二:先在堆中创建空间,里面维护了value属性,指向常量池的ade空间。如果常量池没有"ade",重新创建,如果有,直接通过value指向。最终指向的是堆中的空间地址。

package org.example;

/**
 * @author adekang
 * @version 1.0
 * @date 2023/8/19
 */
public class Integer01 {
    public static void main(String[] args) {

        String s = "ade";
        String d = "ade";
        System.out.println(s == d);   // 所以会相等

        String s2 = new String("ade");
        String s3 = new String("ade");

        System.out.println(s2 == s3);

    }
}

// true
// false

在 Java 中,String.intern() 方法用于将字符串对象添加到字符串常量池中,并返回该字符串在常量池中的引用。如果字符串常量池已经包含了等于该字符串的字符串,则返回常量池中对应字符串的引用。

使用 String.intern() 方法的主要目的是为了节省内存空间和提高字符串的比较效率。当我们多次使用相同的字符串时,通过将字符串对象 intern 后,可以避免创建多个相同内容的字符串对象,而是直接引用已经存在的字符串对象。

下面是一个示例代码:

javaCopy Code
String str1 = new String("Hello");// 创建一个新的字符串对象String str2 = "Hello";// 直接引用常量池中的字符串对象// 使用 intern 方法将 str1 添加到常量池,并返回常量池中的引用String str3 = str1.intern();

System.out.println(str1 == str2);// 输出 false,因为 str1 和 str2 引用的是不同的对象
System.out.println(str2 == str3);// 输出 true,因为 str2 和 str3 引用的是同一个对象

需要注意的是,String.intern() 方法在JDK 6 之前的版本中,会把首次遇到的字符串复制到永久代的字符串常量池中。而在 JDK 7 及以后的版本中,字符串常量池被移到了堆中,因此这种复制行为不会发生。

**String.intern()方法最终返回的是常量池的地址(对象)**

特性

  1. String是一个final类,代表不可变的字符序列
  2. 字符串是不可变的。一个字符串对象一旦被分配, 其内容是不可变的.
package org.example;

/**
 * @author adekang
 * @version 1.0
 * @date 2023/8/19
 */
public class Integer01 {
    public static void main(String[] args) {

        String a = "abc";
        String b = "def";

        String c = a + b;
        String d = "abc" + "def";

        System.out.println(c == "abcdef");  // 堆中相加  false
        System.out.println(d == "abcdef");  // 常量池中相加 true

    }
}

底层是

StringBuilder sb = new StringBuilder();

sb.append(a); sb.append(b);

sb是在堆中,并且append是在原来字符串的基础上追加的. 重要规则:

String c1 = "ab" + "cd";常量相加,看的是池。 String c1 = a + b;变量相加,是在堆中

String类是保存字符串常量的。每次更新都需要重新开辟空间,效率较低,因此java设计者还提供了StringBuilderStringBuffer来增强String的功能,并提高效率。

常用方法

equals //区分大小写,判断内容是否相等

equalslgnoreCase //忽略大小写的判断内容是否相等

length //获取字符的个数,字符串的长度

indexOf //获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回-1

lastlndexOf //获取字符在字符串中最后1次出现的索引,索引从0开始,如找不到,返回-1

substring //截取指定范围的子串

trim //去前后空格

charAt // 获取某索引处的字符,注意不能使用Str[index]这种方式.

toUpperCase // 转换成大写
toLowerCase // 转换成小写
concat // 拼接字符串
replace //  替换字符串中的字符

split // 分割字符串, 对于某些分割字符,我们需要 转义比如 | \\等
toCharArray // 转换成字符数组
compareTo //比较两个字符串的大小,如果前者大,
	        // 则返回正数,后者大,则返回负数,如果相等,返回0
	        // (1) 如果长度相同,并且每个字符也相同,就返回 0
	        // (2) 如果长度相同或者不相同,但是在进行比较时,可以区分大小
	        //     就返回 if (c1 != c2) {
	        //                return c1 - c2;
	        //            }
	        // (3) 如果前面的部分都相同,就返回 str1.len - str2.len
format // 格式字符串
			  //1. %s , %d , %.2f %c 称为占位符
        //2. 这些占位符由后面变量来替换
        //3. %s 表示后面由 字符串来替换
        //4. %d 是整数来替换
        //5. %.2f 表示使用小数来替换,替换后,只会保留小数点两位, 并且进行四舍五入的处理
        //6. %c 使用char 类型来替换
String name = "john";
int age = 10;
double score = 56.857;
char gender = '男';
//将所有的信息都拼接在一个字符串.
String info =
        "我的姓名是" + name + "年龄是" + age + ",成绩是" + score + "性别是" + gender + "。希望大家喜欢我!";
@startuml

!theme plain
top to bottom direction
skinparam linetype ortho

interface CharSequence << interface >> {
  + subSequence(int, int): CharSequence
  + length(): int
  + charAt(int): char
  + compare(CharSequence, CharSequence): int
  + codePoints(): IntStream
  + isEmpty(): boolean
  + toString(): String
  + chars(): IntStream
}
interface Comparable<T> << interface >> {
  + compareTo(T): int
}
interface Constable << interface >> {
  + describeConstable(): Optional<ConstantDesc>
}
interface ConstantDesc << interface >> {
  + resolveConstantDesc(Lookup): Object
}
interface Serializable << interface >>
class String {
  - throwMalformed(int, int): void
  - throwUnmappable(byte[]): void
  ~ join(String, String, String, String[], int): String
  + stripLeading(): String
  + regionMatches(int, String, int, int): boolean
  - throwMalformed(byte[]): void
  + equals(Object?): boolean
  - decode3(int, int, int): char
  + formatted(Object[]?): String
  + stripIndent(): String
  + contains(CharSequence): boolean
  - decode4(int, int, int, int): int
  + toUpperCase(): String
  + toString(): String
  ~ checkBoundsBeginEnd(int, int, int): void
  - isASCII(byte[]): boolean
  + translateEscapes(): String
  - encodeUTF8(byte, byte[], boolean): byte[]
  + getChars(int, int, char[], int): void
  + codePoints(): IntStream
  + join(CharSequence, Iterable<CharSequence>): String
  + matches(String): boolean
  + join(CharSequence, CharSequence[]): String
  - nonSyncContentEquals(AbstractStringBuilder): boolean
  + hashCode(): int
  - encodeASCII(byte, byte[]): byte[]
  - rangeCheck(char[], int, int): Void
  ~ checkOffset(int, int): void
  - isMalformed4(int, int, int): boolean
  - isNotContinuation(int): boolean
  - isMalformed3_2(int, int): boolean
  ~ getBytesUTF8NoRepl(String): byte[]
  + contentEquals(CharSequence): boolean
  + compareTo(String): int
  + indexOf(String, int): int
  ~ checkIndex(int, int): void
  ~ indexOf(byte[], byte, int, String, int): int
  - lookupCharset(String): Charset
  + valueOf(float): String
  + getBytes(int, int, byte[], int): void
  + trim(): String
  + replace(char, char): String
  - indexOfNonWhitespace(): int
  + replace(CharSequence, CharSequence): String
  - scale(int, float): int
  - malformed3(byte[], int): int
  + transform(Function<String, R>): R
  + lastIndexOf(int, int): int
  + replaceAll(String, String): String
  + valueOf(Object?): String
  - encode(Charset, byte, byte[]): byte[]
  + resolveConstantDesc(Lookup?): String
  + split(String): String[]
  + codePointAt(int): int
  ~ coder(): byte
  - encodeUTF8_UTF16(byte[], boolean): byte[]
  ~ valueOfCodePoint(int): String
  - throwUnmappable(int): void
  + length(): int
  - isMalformed3(int, int, int): boolean
  + getBytes(String): byte[]
  + contentEquals(StringBuffer): boolean
  + describeConstable(): Optional<String>
  - encode8859_1(byte, byte[]): byte[]
  + valueOf(boolean): String
  - isMalformed4_3(int): boolean
  ~ newStringUTF8NoRepl(byte[], int, int): String
  - safeTrim(byte[], int, boolean): byte[]
  - newStringNoRepl1(byte[], Charset): String
  + toUpperCase(Locale): String
  + valueOf(int): String
  + toLowerCase(): String
  + valueOf(char): String
  + toCharArray(): char[]
  - getBytesNoRepl1(String, Charset): byte[]
  + chars(): IntStream
  - malformed4(byte[], int): int
  + valueOf(char[], int, int): String
  + codePointCount(int, int): int
  + indexOf(int): int
  + startsWith(String, int): boolean
  ~ getBytes(byte[], int, byte): void
  + codePointBefore(int): int
  + toLowerCase(Locale): String
  + stripTrailing(): String
  + indexOf(String): int
  + startsWith(String): boolean
  + offsetByCodePoints(int, int): int
  - lastIndexOfNonWhitespace(): int
  + format(Locale, String, Object[]?): String
  + valueOf(long): String
  + lastIndexOf(String): int
  - decodeWithDecoder(CharsetDecoder, char[], byte[], int, int): int
  + intern(): String
  ~ checkBoundsOffCount(int, int, int): void
  ~ lastIndexOf(byte[], byte, int, String, int): int
  + isEmpty(): boolean
  + valueOf(double): String
  ~ decodeASCII(byte[], int, char[], int, int): int
  + charAt(int): char
  ~ getBytes(byte[], int, int, byte, int): void
  + concat(String): String
  + regionMatches(boolean, int, String, int, int): boolean
  + valueOf(char[]): String
  + lines(): Stream<String>
  - outdent(List<String>): int
  + copyValueOf(char[], int, int): String
  + repeat(int): String
  + equalsIgnoreCase(String?): boolean
  + substring(int, int): String
  + indent(int): String
  + copyValueOf(char[]): String
  ~ isLatin1(): boolean
  - encode8859_1(byte, byte[], boolean): byte[]
  + lastIndexOf(String, int): int
  - isMalformed4_2(int, int): boolean
  + endsWith(String): boolean
  ~ newStringNoRepl(byte[], Charset): String
  + isBlank(): boolean
  - decodeUTF8_UTF16(byte[], int, int, byte[], int, boolean): int
  + split(String, int): String[]
  + getBytes(): byte[]
  + lastIndexOf(int): int
  ~ value(): byte[]
  + subSequence(int, int): CharSequence
  + compareToIgnoreCase(String): int
  - decode2(int, int): char
  + indexOf(int, int): int
  - encodeWithEncoder(Charset, byte, byte[], boolean): byte[]
  + substring(int): String
  ~ getBytesNoRepl(String, Charset): byte[]
  + strip(): String
  + getBytes(Charset): byte[]
  + format(String, Object[]?): String
  + replaceFirst(String, String): String
}

String        -[#008200,dashed]-^  CharSequence 
String        -[#008200,dashed]-^  Comparable   
String        -[#008200,dashed]-^  Constable    
String        -[#008200,dashed]-^  ConstantDesc 
String        -[#008200,dashed]-^  Serializable 
@enduml

StringBuffer

java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删。很多方法与String相同,但StringBuffer是可变长度的。

StringBuffer是一个容器。

String VS StringBuffer

  1. String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低 //private final char value[];
  2. StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高 //char[] value; //这个放在堆.

StringBuffer 与 String 相互转换

package org.example.StringBuffer_;

public class StringBuffer01 {
  public static void main(String[] args) {
    String str = "hello";

    // 方式一 通过构造器 返回的是一个StringBuffer对象,对str本身没有影响
    StringBuffer stringBuffer = new StringBuffer(str);

    // 方式二 通过append方法 返回的是一个StringBuffer对象,对str本身没有影响
    StringBuffer stringBuffer2 = new StringBuffer();
    stringBuffer2.append(str);

    // 方式三 通过toString方法 返回的是一个String对象
    StringBuffer stringBuffer3 = new StringBuffer("hello");
    String string = stringBuffer3.toString();
    String string2 = new String(string);
    //

  }
}

StringBuffer 常见类

StringBuffer是Java中一个用于操作字符串的类。StringBuffer的常见用法有:

  1. 追加字符串

可以使用StringBuffer的append()方法追加任意类型的数据到字符串末尾。

例如:

codeStringBuffer sb = new StringBuffer();
sb.append("Hello ");
sb.append("World");
System.out.println(sb.toString());// 输出Hello World
  1. 插入字符串

可以使用StringBuffer的insert()方法在指定索引位置插入字符串。

例如:

codeStringBuffer sb = new StringBuffer("Hello");
sb.insert(5," Java");
System.out.println(sb.toString());// 输出Hello Java
  1. 替换字符串

可以使用StringBuffer的replace()方法替换指定区间内的字符串。

例如:

codeStringBuffer sb = new StringBuffer("Hello");
sb.replace(0,5,"Hi");
System.out.println(sb.toString());// 输出Hi
  1. 删除字符串

可以使用StringBuffer的delete()方法删除指定区间内的字符串。

例如:

codeStringBuffer sb = new StringBuffer("Hello");
sb.delete(0,3);
System.out.println(sb.toString());// 输出lo
  1. 反转字符串

可以使用StringBuffer的reverse()方法反转字符串。

例如:

codeStringBuffer sb = new StringBuffer("Hello");
sb.reverse();
System.out.println(sb.toString());// 输出olleH

这些是StringBuffer的一些常见用法。相比String,StringBuffer可以高效地对字符串进行修改操作。

StringBuilder

1)一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全)。该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,它比StringBuffer要快。

2)在StringBuilder上的主要操作是append和insert方法,可重载这些方法, 以接受任意类型的数据。

StringBuilder继承AbstractStringBuilder 类

实现了Serializable , 说明StringBuilder对象是可以串行化(对象可以网络传输,可以保存到文件)

StringBuilder是final类,不能被继承

StringBuilder对象字符序列仍然是存放在其父类AbstractStringBuilder的 char[] vaLue ;

因此,

StringBuilder的方法,没有做互斥的处理,即没有synchronized关键字,因此在单线程的情况下使用StringBuilder

Untitled转存失败,建议直接上传图片文件

String、StringBuffer 和StringBuilder的比较

StringBuilder和StringBuffer非常类似,均代表可变的字符序列,而且方法也一样 String: 不可变字符序列,效率低,但是复用率高。 StringBuffer:可变字符序列、效率较高(增删)、线程安全,看源码 StringBuilder:可变字符序列、效率最高、线程不安全 String使用注意说明: string s=" a"; //创建了一个字符串 s+="b"; //实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s+"b" (也就是" ab").如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能=>结论:如果我们对String做大量修改,不要使用String

使用的原则,结论:

1.如果字符串存在大量的修改操作,一般使用StringBufferStringBuilder

2.如果字符串存在大量的修改操作,并在单线程的情况,使用StringBuilder

3.如果字符串存在大量的修改操作,并在多线程的情况,使用StringBuffer

4.如果我们字符串很少修改,被多个对象引用,使用String, 比如配置信息等

Math类

Math类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。

Java Math类是java.lang包下提供各种数学运算功能的一个类。Math类中的常用方法有:

  1. abs():求绝对值
int absValue = Math.abs(-10); // absValue为10
  1. ceil():向上取整
double ceilValue = Math.ceil(10.1); // ceilValue 为11.0
  1. floor():向下取整
double floorValue = Math.floor(10.9); // floorValue 为10.0
  1. round():四舍五入
long roundValue = Math.round(10.4); // roundValue 为10
  1. max():求两值中的最大值
int maxValue = Math.max(100, 200); // maxValue 为200
  1. min():求两值中的最小值
int minValue = Math.min(100, 200); // minValue 为100
  1. pow():求幂
double powValue = Math.pow(2, 3); // powValue 为8.0
  1. sqrt(): 求平方根
double sqrtValue = Math.sqrt(100); // sqrtValue 为10.0
  1. random():产生随机数
double randomValue = Math.random(); // randomValue 为0.0到1.0之间的随机数

这些是Java Math类中常用的一些静态方法。通过Math可以方便地进行数学计算。

Arrays

Arrays里面包含了一系列静态方法,用于管理或操作数组(比如排序和搜索)

这里是一些Arrays类中常用的方法:

- toString(int[] a) - 将数组转换为字符串
- sort(int[] a) - 对数组进行排序
- binarySearch(int[] a, int key) - 对排序后的数组进行二分查找
- copyOf(int[] a, int newLength) - 复制数组
- fill(int[] a, int val) - 用指定值填充数组
- equals(int[] a, int[] b) - 判断两个数组是否相等
- asList(int[] a) - 将数组转换为List
- copyOfRange(int[] a, int from, int to) - 复制数组的某个范围
- deepToString(Object[] a) - 将多维数组转换为字符串
- deepEquals(Object[] a1, Object[] a2) - 判断多维数组是否相等
- parallelSort(int[] a) - 对数组进行并行排序
- setAll(int[] a, IntFunction generator) - 使用函数设置数组值
- parallelPrefix(int[] a, BinaryOperator op) - 对数组进行并行前缀计算
- spliterator(int[] a) - 获取数组的spliterator 

这些是Arrays类中非常有用的方法,可以方便我们操作数组。

自定义排序

package org.example;

import java.util.Arrays;
import java.util.Comparator;

public class ArraysSortCustom {
  public static void main(String[] args) {
    Integer[] integer = { 1, 20, 50, 30 };

    bubble(integer, new Comparator() {
      @Override
      public int compare(Object o1, Object o2) {
        Integer i1 = (Integer) o1;
        Integer i2 = (Integer) o2;
        return i2 - i1;
      }
    });

    System.out.println(Arrays.toString(integer));

  }

  public static void bubble(Integer[] integer) {
    for (int i = 0; i < integer.length - 1; i++) {
      for (int j = 0; j < integer.length - 1 - i; j++) {
        if (integer[j] > integer[j + 1]) {
          int temp = integer[j];
          integer[j] = integer[j + 1];
          integer[j + 1] = temp;
        }
      }
    }
  }

  public static void bubble(Integer[] integer, Comparator c) {
    for (int i = 0; i < integer.length - 1; i++) {
      for (int j = 0; j < integer.length - 1 - i; j++) {
        if (c.compare(integer[j], integer[j + 1]) > 0) {
          int temp = integer[j];
          integer[j] = integer[j + 1];
          integer[j + 1] = temp;
        }
      }
    }
  }
}

案例

package org.example;

import java.util.Arrays;
import java.util.Comparator;

public class ArraysSortCustom {
  public static void main(String[] args) {
    Book[] books = new Book[4];
    books[0] = new Book("Java", 10);
    books[1] = new Book("Python", 60);
    books[2] = new Book("C++", 5);
    books[3] = new Book("C", 40);

    // Arrays.sort(books, (o1, o2) -> o2.getPrice() - o1.getPrice());
    Arrays.sort(books, new Comparator() {
      @Override
      public int compare(Object o1, Object o2) {
        Book book1 = (Book) o1;
        Book book2 = (Book) o2;
        return book2.getPrice() - book1.getPrice();
      }
    });

    System.out.println(Arrays.toString(books));
  }

}

class Book {
  private String name;
  private Integer price;

  public Book(String name, Integer price) {
    this.name = name;
    this.price = price;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Integer getPrice() {
    return price;
  }

  public void setPrice(Integer price) {
    this.price = price;
  }

  @Override
  public String toString() {
    return "Book [name=" + name + ", price=" + price + "]";
  }

}

System

这里有一些Java System类常用的方法:

- currentTimeMillis() - 返回当前时间(以毫秒为单位)
- arraycopy() - 复制数组的一部分到另一个数组
- gc() - 运行垃圾回收器
- exit() - 退出当前运行的Java虚拟机
- getProperty() - 获取系统属性的值
- setProperty() - 设置系统属性的值
- getenv() - 获取环境变量的值
- nanoTime() - 返回高分辨时间(纳秒)
- console() - 返回与当前Java虚拟机相关的控制台
- currentTimeMillis()与nanoTime()常用于计时和基准测试。
- getProperty()和setProperty()用于获取和设置系统属性。
- exit()可以直接关闭虚拟机。
- gc()可以手动提醒JVM进行垃圾回收。
- console()可以获取控制台输入输出流。

System类中还有一些其他常用的方法,比如load(), loadLibrary()等。这些就是Java System类中比较常用的一些静态方法。

BigInteger & BigDecimal

BigInteger适合保存比较大的整型 BigDecimal适合保存精度更高的浮点型(小数)

BigInteger 在 Java 中主要用于大整数的运算,可以表示任意大小的整数,适用于需要大数值精度的场景。

BigInteger 的常见用法包括:

  1. 创建 BigInteger 对象

可以直接通过构造函数创建:

BigInteger bi1 = new BigInteger("123456789");

也可以使用静态的 valueOf() 方法创建:

BigInteger bi2 = BigInteger.valueOf(123456789);
  1. 进行算术运算

BigInteger 支持常见的加、减、乘、除等算术运算,通过调用实例方法完成:

BigInteger sum = bi1.add(bi2);
BigInteger diff = bi1.subtract(bi2);
  1. 比较大小

可以使用 compareTo() 方法比较两个 BigInteger 的大小:

int cmp = bi1.compareTo(bi2);
  1. 转换为其他数值类型

可以使用 intValue()longValue() 等方法转换为基本类型:

int intVal = bi1.intValue();
long longVal = bi1.longValue();
  1. 格式化输出

可以使用 toString() 方法格式化为字符串输出:

String str = bi1.toString();

需要注意 BigInteger 是不可变对象,运算不会改变原对象的值,而是产生新的对象。

BigInteger 可以表示任意大小的整数,适合高精度运算场景。

package org.example.BigInterger;

import java.math.BigInteger;

public class BigInteger_ {
  public static void main(String[] args) {
    BigInteger bi = new BigInteger("12345678901234567890");
    BigInteger b = new BigInteger("9");
    BigInteger a = bi.add(b);

    System.out.println(a);

  }
}

BigDecimal 在 Java 中主要用于高精度计算,适用于需要准确计算和避免浮点数误差的场景。

BigDecimal 的常见用法包括:

  1. 创建 BigDecimal 对象

可以通过 BigDecimal 构造函数创建,通常需要指定一个字符串或 double 值:

BigDecimal bd1 = new BigDecimal("123.456");
BigDecimal bd2 = new BigDecimal(123.456);
  1. 进行算术运算

通过 BigDecimal 的 add()subtract()multiply()divide() 等方法进行各种运算。运算结果也是 BigDecimal 对象。

BigDecimal result = bd1.add(bd2);
  1. 比较大小

可以使用 compareTo() 方法比较两个 BigDecimal 的大小。

int cmp = bd1.compareTo(bd2);
  1. 四舍五入

可以使用 setScale() 方法设置小数位数,多余的小数位会自动四舍五入。

BigDecimal bd3 = bd1.setScale(2, RoundingMode.HALF_UP);
  1. 格式化输出

可以使用 toString() 方法格式化输出。

String str = bd3.toString(); // "123.46"

需要注意 BigDecimal 对象是不可变的,大多数方法都会返回一个新的 BigDecimal 对象,不会修改原对象。

日期类

Date

Date:精确到毫秒,代表特定的瞬间 SimpleDateFormat:格式和解析日期的类 SimpleDateFormat格式化和解析日期的具体类。它允许进行格式化(日期->文本)、解析(文本->日期)和规范化.

Date 类在 Java 中用于表示日期和时间,但有一些特点需要注意:

  1. Date 表示的时间是自 1970年1月1日 00:00:00 GMT 开始经过的毫秒数。
  2. Date 中的年份是从 1900 开始的,月份从 0 开始计数。
  3. Date 类存在线程安全问题,是非线程安全的。
  4. Date 的大多数方法已经废弃,不推荐使用。

Date 的常见用法:

  1. 获取当前时间系统时间:
Date date = new Date();
  1. 通过指定毫秒数创建 Date:
Date date2 = new Date(1646870400000L);
  1. 获取日期信息:
int year = date.getYear(); 
int month = date.getMonth(); 
int day = date.getDate();
  1. 比较日期先后:
Date date1 = new Date();
Date date2 = new Date(date1.getTime() + 86400);

if(date1.before(date2)) {
  // ...
}
  1. 格式化日期

可以通过 SimpleDateFormat 格式化和解析日期。

package org.example.Date;

import java.text.SimpleDateFormat;
import java.util.Date;

public class Date01 {
  public static void main(String[] args) {
    Date d = new Date();

    System.out.println(d);

    // 格式转换
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String format = simpleDateFormat.format(d);
    System.out.println(format);
  }
}

Date 类存在缺陷,在 JDK 1.1 引入了 Calendar 和 DateFormat 类,在 JDK 1.8 后推荐使用 LocalDate、LocalTime、LocalDateTime 等新 API。

Calendar

Calendar 类在 Java 中主要用来完成日期和时间的运算和格式化,相比于 Date 类有几个特点:

  1. Calendar 表示的时间精确到毫秒,可以用于更复杂的日期和时间计算。
  2. Calendar 是抽象类,通常使用它的子类 GregorianCalendar 来创建实例。
  3. Calendar 是线程安全的,可以被多个线程共享。
  4. Calendar 支持不同时区。

Calendar 的常见用法包括:

  1. 创建 Calendar 实例,默认是当前日期时间:
Calendar c = Calendar.getInstance();
  1. 获取日期时间信息:
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) + 1; //月份从0开始
int day = c.get(Calendar.DAY_OF_MONTH);
  1. 修改日期时间信息:
c.set(Calendar.YEAR, 2022);
c.set(Calendar.MONTH, 11); //11表示12月
  1. 进行日期时间计算:
//日期+1天
c.add(Calendar.DAY_OF_MONTH, 1);

//日期-3个月
c.add(Calendar.MONTH, -3);
  1. 比较日期先后顺序:
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();

if (c1.before(c2)) {
  // ...
}
  1. 格式化日期时间:

可以使用 SimpleDateFormat 格式化 Calendar 对象。

Calendar 克服了 Date 的很多缺点,但在 JDK 1.8 后也推荐使用更简洁的 LocalDateTime。

Calendar类之后被弃用了。而Calendar也存在问题是:

1)可变性:像日期和时间这样的类应该是不可变的。

2)偏移性: Date中的年份是从1900开始的, 而月份都从0开始。

3)格式化:格式化只对Date有用,Calendar则不行。

4)此外,它们也不是线程安全的;不能处理闰秒等(每隔2天,多出1s)

LocalDateTime

LocalDateTime 是 Java 8 中加入的新日期时间 API,与旧的 Date 和 Calendar 相比有以下优点:

  1. 不可变对象,线程安全。
  2. 语义更清晰,方法用法更简单。
  3. 不包含时区信息,可以避免时区处理的复杂性。
  4. 提供更丰富的方法来操作日期时间。
  5. 日期时间计算更方便、安全。

LocalDateTime 的常见用法:

  1. 获取当前日期时间:
LocalDateTime now = LocalDateTime.now();
  1. 从指定日期时间创建:
LocalDateTime dt = LocalDateTime.of(2022, 3, 8, 15, 20, 30);
  1. 获取详细信息:
int year = dt.getYear();
Month month = dt.getMonth();
int day = dt.getDayOfMonth();
  1. 日期时间运算:
LocalDateTime dt2 = dt.plusDays(3); //3天后
LocalDateTime dt3 = dt.minusWeeks(2); //2周前
  1. 比较日期先后:
if(dt1.isBefore(dt2)) {
  // ...
}
  1. 格式化:
String strDt = dt.format(DateTimeFormatter.ISO_DATE_TIME);

LocalDateTime 极大地简化了日期时间的操作,是先进的日期时间 API。

DateTimeFormatter 是 Java 8 中日期时间格式化的工具类。它可以用来格式化和解析 LocalDateTime、LocalDate 等新日期时间 API。

DateTimeFormatter 的使用包括:

  1. 获取系统默认格式化器:
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
  1. 获取预定义的格式化器:
DateTimeFormatter formatter = DateTimeFormatter.BASIC_ISO_DATE;
  1. 自定义格式化器:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  1. 格式化日期时间:
LocalDateTime dt = LocalDateTime.now();
String str = dt.format(formatter);
  1. 解析字符串为日期时间:
LocalDateTime dt = LocalDateTime.parse(str, formatter);

DateTimeFormatter 预定义了多种常用的格式化器,也可以自定义格式化模式。

相比 SimpleDateFormat,DateTimeFormatter 是线程安全的,可以明确指定时区,而且与新日期时间 API 整合更好。