Java函数

1 Math

1.1 简介

数学函数

1.2 常用方法

sqrt(x) 平方根

public class class2{
    public static void main(String[] args){
        double x=4;
        double y = Math.sqrt(x);
        System.out.println(y);
    }
}

pow(x,a) 幂运算

double y = Math.pow(x,a)

将y值设置为x的a次幂。pow方法接收两个double类型的参数,其返回结果也为double类型

三角函数

  • .sin()
  • .cos()
  • .tan()
  • .atan()
  • .atan2()

指数函数以及他的反函数--自然对数以及以10为底的对数

  • .exp()
  • .log()
  • .log10()

用于表示π和e常量的最接近的近似值

  • .PI
  • .E

2 Scanner 类使用指南

目录

1. 基本导入和创建

import java.util.Scanner;  // 必须导入

// 从标准输入(键盘)创建
Scanner sc = new Scanner(System.in);

// 从字符串创建(用于测试)
Scanner stringScanner = new Scanner("Hello 123 45.6");

// 从文件创建
Scanner fileScanner = new Scanner(new File("data.txt"));

2. 基本数据类型读取方法

方法 返回值 说明 示例
nextInt() int 读取下一个整数 int num = sc.nextInt();
nextDouble() double 读取下一个双精度浮点数 double d = sc.nextDouble();
nextFloat() float 读取下一个单精度浮点数 float f = sc.nextFloat();
nextLong() long 读取下一个长整数 long l = sc.nextLong();
nextShort() short 读取下一个短整数 short s = sc.nextShort();
nextByte() byte 读取下一个字节 byte b = sc.nextByte();
nextBoolean() boolean 读取下一个布尔值 boolean bool = sc.nextBoolean();

3. 字符串和字符读取方法

方法 返回值 说明 示例
next() String 读取下一个单词(到空格为止) String word = sc.next();
nextLine() String 读取下一行文本(包括空格) String line = sc.nextLine();
使用charAt(0) char 读取单个字符 char c = sc.next().charAt(0);

4. 判断方法(检查输入)

方法 返回值 说明 示例
hasNextInt() boolean 检查是否有下一个整数 if(sc.hasNextInt()) {...}
hasNextDouble() boolean 检查是否有下一个双精度数 while(sc.hasNextDouble()) {...}
hasNext() boolean 检查是否有下一个单词 while(sc.hasNext()) {...}
hasNextLine() boolean 检查是否有下一行 while(sc.hasNextLine()) {...}

5. 实用技巧和注意事项

处理换行符问题

Scanner sc = new Scanner(System.in);

System.out.print("请输入年龄: ");
int age = sc.nextInt();      // 读取数字,但换行符留在缓冲区

sc.nextLine();               // 消耗掉换行符(重要!)

System.out.print("请输入姓名: ");
String name = sc.nextLine(); // 现在可以正确读取整行

使用分隔符

Scanner sc = new Scanner("apple,banana,orange");
sc.useDelimiter(",");        // 设置逗号为分隔符

while(sc.hasNext()) {
    System.out.println(sc.next()); // 输出: apple banana orange
}

输入验证示例

Scanner sc = new Scanner(System.in);
int number;

System.out.print("请输入一个整数: ");
while (!sc.hasNextInt()) {   // 如果不是整数
    System.out.println("输入错误,请重新输入整数: ");
    sc.next();               // 消耗掉错误的输入
}
number = sc.nextInt();       // 读取正确的整数

6. 完整使用示例

import java.util.Scanner;

public class ScannerExample {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        // 读取不同类型的数据
        System.out.print("请输入姓名: ");
        String name = sc.nextLine();
        
        System.out.print("请输入年龄: ");
        int age = sc.nextInt();
        
        System.out.print("请输入身高(米): ");
        double height = sc.nextDouble();
        
        System.out.print("是否学生(true/false): ");
        boolean isStudent = sc.nextBoolean();
        
        // 输出结果
        System.out.println("\n--- 用户信息 ---");
        System.out.println("姓名: " + name);
        System.out.println("年龄: " + age);
        System.out.println("身高: " + height + "米");
        System.out.println("学生: " + isStudent);
        
        sc.close(); // 记得关闭Scanner
    }
}

7. 重要注意事项

  1. 必须导入import java.util.Scanner;
  2. 及时关闭:使用完后调用 sc.close() 释放资源
  3. 处理异常:读取时可能抛出 InputMismatchException
  4. 缓冲区问题:注意 nextInt() 等数字读取方法后的换行符问题
  5. 资源管理:如果从文件创建,确保处理 FileNotFoundException

8. 常见错误避免

错误:混合使用 nextLine() 和数字读取方法
正确:在数字读取后加 sc.nextLine() 消耗换行符

错误:不检查输入类型直接读取
正确:使用 hasNextInt() 等方法先验证

3 Random 类使用指南

目录

1. 基本导入和创建

import java.util.Random;  // 必须导入

// 创建Random对象(无参构造,使用系统时间作为种子)
Random random = new Random();

// 创建Random对象(指定种子,可重现随机序列)
Random seededRandom = new Random(12345L);

2. 基本数据类型生成方法

方法 返回值 说明 示例
nextInt() int 生成所有可能的整数(包括负数) int num = random.nextInt();
nextInt(int bound) int 生成[0, bound)范围的随机整数 int num = random.nextInt(10);
nextDouble() double 生成[0.0, 1.0)范围的随机小数 double d = random.nextDouble();
nextFloat() float 生成[0.0, 1.0)范围的随机小数 float f = random.nextFloat();
nextLong() long 生成所有可能的长整数 long l = random.nextLong();
nextBoolean() boolean 生成true或false boolean bool = random.nextBoolean();

3. 指定范围的随机数生成

生成指定范围的整数

Random random = new Random();

// 生成 [0, 10) 的随机整数(0-9)
int num1 = random.nextInt(10);

// 生成 [1, 11) 的随机整数(1-10)
int num2 = random.nextInt(10) + 1;

// 生成 [min, max] 的随机整数(通用公式)
int min = 5;
int max = 15;
int num3 = random.nextInt(max - min + 1) + min;

生成指定范围的小数

Random random = new Random();

// 生成 [0.0, 10.0) 的随机小数
double d1 = random.nextDouble() * 10;

// 生成 [5.0, 15.0) 的随机小数
double d2 = random.nextDouble() * 10 + 5;

// 生成 [min, max) 的随机小数(通用公式)
double min = 2.5;
double max = 7.5;
double d3 = random.nextDouble() * (max - min) + min;

4. 其他数据类型生成

生成随机字符

Random random = new Random();

// 生成随机小写字母
char lowerCase = (char) ('a' + random.nextInt(26));

// 生成随机大写字母
char upperCase = (char) ('A' + random.nextInt(26));

// 生成随机字母(大小写混合)
char randomLetter = (char) (random.nextBoolean() ? 
                          'a' + random.nextInt(26) : 
                          'A' + random.nextInt(26));

生成随机数组

Random random = new Random();
int[] randomArray = new int[10];

// 生成包含10个随机数的数组(0-99)
for (int i = 0; i < randomArray.length; i++) {
    randomArray[i] = random.nextInt(100);
}

5. 种子(Seed)的使用

// 使用相同种子的Random对象会生成相同的随机序列
Random random1 = new Random(42L);
Random random2 = new Random(42L);

// 这两个对象将生成完全相同的随机数序列
System.out.println(random1.nextInt(100)); // 总是相同的值
System.out.println(random2.nextInt(100)); // 与上面相同

// 用于测试和调试,确保结果可重现

6. 完整使用示例

import java.util.Random;

public class RandomExample {
    public static void main(String[] args) {
        Random random = new Random();
        
        // 生成各种类型的随机数
        System.out.println("随机整数: " + random.nextInt());
        System.out.println("0-99的随机数: " + random.nextInt(100));
        System.out.println("1-100的随机数: " + (random.nextInt(100) + 1));
        System.out.println("随机小数: " + random.nextDouble());
        System.out.println("随机布尔值: " + random.nextBoolean());
        
        // 生成指定范围的随机数
        int min = 10;
        int max = 20;
        int rangeRandom = random.nextInt(max - min + 1) + min;
        System.out.println("10-20的随机数: " + rangeRandom);
        
        // 生成随机字母
        char randomChar = (char) ('A' + random.nextInt(26));
        System.out.println("随机大写字母: " + randomChar);
    }
}

7. 重要注意事项

  1. 必须导入import java.util.Random;
  2. 范围理解nextInt(n) 生成 [0, n) 范围的整数
  3. 种子使用:指定种子可以重现随机序列,适合测试场景
  4. 性能考虑:Random类线程安全但性能一般,高并发场景考虑ThreadLocalRandom
  5. 安全性:Random不适合密码学用途,需要安全随机数时使用SecureRandom

4 开箱即用的函数

String! 字符串相关

  • .trim():去掉头尾空格
  • .split(正则):通过正则表达式来分割字符串

1. 长度

String s = "Hello";
System.out.println(s.length());

2. 遍历字符串

for (int i = 0; i < s.length(); i++) {
    System.out.println(s.charAt(i));
}

3. String → int

int n = Integer.parseInt("123");

4. 其他类型 → String

String s1 = String.valueOf(100);
String s2 = 3.14 + "";

5. Substring(截取)

String s = "HelloWorld";
System.out.println(s.substring(0, 5));

6. 检查格式(正则)

String phone = "13812345678";
boolean ok = phone.matches("\d{11}");

7. 访问某个位置字符

char c = s.charAt(2);

8. 查找字符串位置

int index = s.indexOf("lo");

9. 字符串比较

if (s.equals("Hello")) { }

10. 分割字符串

String[] arr = "a,b,c".split(",");

11. 字符串替换

String s2 = "a-b-c".replace("-", "_");

12. 去除头尾空格

String t = "  hi  ".trim();

13. 字符串转字符数组

String str = "Hello";
char[] chars = str.toCharArray();

for (char c : chars) {
    System.out.println(c);
}

14.从字符数组新建字符串

char[] abc_list = word.toCharArray();  
String sort_word = new String(abc_list);

5 Arrays! 类使用指南

工具类:java.util.Arrays


1. 排序

int[] arr = {5, 3, 9, 1};
Arrays.sort(arr);  
System.out.println(Arrays.toString(arr)); // [1, 3, 5, 9]
  • 默认升序
  • 降序需结合 Collections.reverseOrder() 或手动实现

2. 转字符串输出

int[] arr = {1, 2, 3};
System.out.println(Arrays.toString(arr));  // [1, 2, 3]

3. 填充数组

int[] arr = new int[5];
Arrays.fill(arr, 7);
System.out.println(Arrays.toString(arr));  // [7, 7, 7, 7, 7]

4. 复制数组

int[] arr = {1, 2, 3};
int[] copy = Arrays.copyOf(arr, 5);
System.out.println(Arrays.toString(copy)); // [1, 2, 3, 0, 0]

5. 复制部分数组

int[] arr = {1, 2, 3, 4, 5};
int[] sub = Arrays.copyOfRange(arr, 1, 4);
System.out.println(Arrays.toString(sub)); // [2, 3, 4]
  • 区间 [from, to) 左闭右开

6. 比较数组

int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3};
System.out.println(Arrays.equals(arr1, arr2));  // true

7. 二分查找

int[] arr = {1, 3, 5, 7, 9};
int index = Arrays.binarySearch(arr, 5);
System.out.println(index);  // 2
  • 前提:数组必须有序
  • 没找到返回负数

8. 并行排序(JDK 8+)

int[] arr = {9, 7, 5, 3, 1};
Arrays.parallelSort(arr);
System.out.println(Arrays.toString(arr));  // [1, 3, 5, 7, 9]
  • 大数组时利用多线程提升性能

9. 多维数组打印

int[][] arr = {{1,2}, {3,4}};
System.out.println(Arrays.deepToString(arr));
// [[1, 2], [3, 4]]
  • 一维数组用 toString,多维数组用 deepToString

10. 流式操作(JDK 8+)

int[] arr = {1, 2, 3, 4, 5};
int sum = Arrays.stream(arr).sum();
System.out.println(sum);  // 15
  • 可结合 map / filter 等流操作

总结记忆口诀

  • 排序sort / parallelSort
  • 输出toString / deepToString
  • 填充fill
  • 复制copyOf / copyOfRange
  • 比较equals
  • 查找binarySearch
  • stream

6 Integer 类使用指南

Integerjava.lang.Integer 包装类。
它把基本类型 int 包装成对象,并提供很多静态方法和实例方法

示例代码

nums[i] = Integer.parseInt(line[i]);

这里的 Integerjava.lang.Integer 包装类。它提供了许多静态方法和实例方法。


一、静态方法(工具类方法)

1. 类型转换

  • parseInt(String s):把字符串转为 int
  • parseInt(String s, int radix):指定进制解析字符串
  • valueOf(String s):返回 Integer 对象
  • valueOf(String s, int radix):指定进制返回 Integer 对象

2. 进制转换

  • toString(int i):把整数转为字符串
  • toString(int i, int radix):以指定进制转为字符串
  • toBinaryString(int i):转二进制字符串
  • toOctalString(int i):转八进制字符串
  • toHexString(int i):转十六进制字符串

3. 比较 / 数学相关

  • compare(int x, int y):比较两个整数大小
  • max(int a, int b):返回较大值
  • min(int a, int b):返回较小值
  • sum(int a, int b):返回和
  • compareUnsigned(int x, int y):按无符号比较
  • divideUnsigned(int dividend, int divisor):无符号相除
  • remainderUnsigned(int dividend, int divisor):无符号取余

二、实例方法(作用在 Integer 对象上)

1. 取值

  • intValue():返回 int
  • longValue():返回 long
  • floatValue():返回 float
  • doubleValue():返回 double
  • byteValue():返回 byte
  • shortValue():返回 short

2. 比较

  • compareTo(Integer anotherInteger):与另一个 Integer 比较大小
  • equals(Object obj):比较内容是否相等

3. 杂项

  • toString():返回字符串表示
  • hashCode():返回哈希值

三、常量字段

  • Integer.MAX_VALUEint 最大值(2^31 - 1
  • Integer.MIN_VALUEint 最小值(-2^31
  • Integer.SIZEint 的二进制位数(32)
  • Integer.BYTESint 占用字节数(4)
  • Integer.TYPEint.class

四、总结

  • Integer.parseInt() → 常用来将字符串转换为 int
  • 提供 常量(最大/最小值)、类型转换(基本类型 ↔ 对象)、进制转换比较 等功能
  • 静态方法偏工具类,实例方法偏对象操作

7 栈和队列

Stack(栈)

1. 初始化

Stack<Integer> st = new Stack<>();

2. 压栈 / 出栈

st.push(10);
int x = st.pop();

3. empty

st.empty();

4. 访问栈顶

int top = st.peek();

Queue(队列)

1. 初始化

Queue<Integer> q = new LinkedList<>();

2. 入队 / 出队

q.offer(10);
int x = q.poll();

3. 查看队头

int head = q.peek();

8 Collections! 专门操作List的类

1. Collections 的作用

Collections 类是 Java 集合框架的工具类,用于对 List、Set、Map
等集合进行操作。它提供排序、反转、查找、线程安全包装等常用功能。

2. Collections 的主要功能

(1)集合排序

Collections.sort(list); // 升序
Collections.sort(list, Collections.reverseOrder()); // 降序

(2)反转序列

Collections.reverse(list);

(3)随机打乱(shuffle)

Collections.shuffle(list);

(4)最大值、最小值

Collections.max(list);
Collections.min(list);

(5)统计出现次数

Collections.frequency(list, "abc");

(6)线程安全包装

List list = Collections.synchronizedList(new ArrayList<>());
Map map = Collections.synchronizedMap(new HashMap<>());

(7)不可变集合

List<String> list = Collections.unmodifiableList(someList);

(8)填充、替换

Collections.fill(list, "aaa");
Collections.replaceAll(list, "a", "b");

(9)二分查找

Collections.binarySearch(list, "key");

3. Collections 与 Arrays 的区别

工具类 作用对象 常用功能
Arrays 数组 array[] 排序、复制、转字符串
Collections 集合 List/Set/Map 排序、反转、查找、同步/只读包装

9 Character! Char字符类型(包装后)

判断字符类型

  • Character.isUpperCase(char ch):是否为大写字母\
  • Character.isLowerCase(char ch):是否为小写字母\
  • Character.isDigit(char ch):是否为数字\
  • Character.isLetter(char ch):是否为字母\
  • Character.isLetterOrDigit(char ch):是否为字母或数字\
  • Character.isWhitespace(char ch):是否为空白字符

字符转换

  • Character.toUpperCase(char ch):转为大写\
  • Character.toLowerCase(char ch):转为小写

其他常用方法

  • Character.isDefined(char ch):判断是否是已定义的 Unicode 字符\
  • Character.isSpaceChar(char ch):是否为空格字符\
  • Character.getType(char ch):获取字符的 Unicode 类型\
  • Character.isTitleCase(char ch):是否为标题大小写字符

10 Regex! 正则表达式解析字符串

导入:java.util.regex

核心类:

Pattern 编译正则表达式
Matcher 根据 Pattern 对文本执行匹配、查找、分组等操作

一、基础用法:判断字符串是否匹配

boolean result = "abc123".matches("[a-z]+\d+");
System.out.println(result); // true

二、推荐用法:Pattern + Matcher

1. 查找(find)

Pattern pattern = Pattern.compile("\d+");
Matcher matcher = pattern.matcher("abc123xyz456");

while (matcher.find()) {
    System.out.println(matcher.group());   // 输出 123 和 456
}

三、捕获组(分组解析字符串)

示例解析:"name=Tom;age=20;city=Beijing"

String text = "name=Tom;age=20;city=Beijing";

Pattern pattern = Pattern.compile("(\\w+)=(\\w+)");//注意这里要双重转义
Matcher matcher = pattern.matcher(text);

while (matcher.find()) {
    String key = matcher.group(1);
    String value = matcher.group(2);
    System.out.println(key + " -> " + value);
}

四、提取复杂结构

String log = "127.0.0.1 - - [12/Dec/2025:12:45:32] \"GET /index HTTP/1.1\"";

Pattern p = Pattern.compile(
        "(\d+\.\d+\.\d+\.\d+).*?\[(.*?)\].*?\"(GET|POST|PUT|DELETE)"
);
Matcher m = p.matcher(log);

if (m.find()) {
    System.out.println("IP: " + m.group(1));
    System.out.println("Time: " + m.group(2));
    System.out.println("Method: " + m.group(3));
}

五、替换与变形

简单替换

String r = "a1b2c3".replaceAll("\d", "*");
System.out.println(r); // a*b*c*

使用分组进行替换

String phone = "010-12345678";

String res = phone.replaceAll("(\d{3})-(\d+)", "$1 ****");
System.out.println(res); // 010 ****

六、命名捕获组(Java 7+)

String input = "id=42,name=Tom,age=18";

Pattern p = Pattern.compile("id=(?<id>\d+),name=(?<name>\w+),age=(?<age>\d+)");
Matcher m = p.matcher(input);

if (m.find()) {
    System.out.println(m.group("id"));
    System.out.println(m.group("name"));
    System.out.println(m.group("age"));
}

七、完整封装示例

public static Map<String, String> parse(String str) {
    Map<String, String> map = new HashMap<>();
    Pattern p = Pattern.compile("(\w+)=(\w+)");
    Matcher m = p.matcher(str);

    while (m.find()) {
        map.put(m.group(1), m.group(2));
    }
    return map;
}

public static void main(String[] args) {
    String s = "name=Tom age=18 city=Beijing";
    System.out.println(parse(s));
}

八、常用正则表达式整理

功能 正则


匹配数字 \d+
匹配字母 [a-zA-Z]+
匹配邮箱 \w+@\w+\.\w+
匹配 IPv4 (\d{1,3}\.){3}\d{1,3}
匹配中文 [一-龥]+

11 Instant 时间相关类

import java.time.Instant;

Instant 是 Java 8 新时间 API (java.time) 中表示时间线上的一个瞬时时刻的类。它主要用于表示:

一个绝对时间点,与时区无关。

比如:

2026-07-26T10:30:00Z

表示 UTC 时间 2026 年 7 月 26 日 10:30:00。

它适合:

  • 记录数据库时间
  • 记录日志时间
  • JWT过期时间
  • 计算时间间隔
  • 服务之间传递时间戳

Instant 内部基于 Unix 时间戳,从:

1970-01-01T00:00:00Z

开始计算。它内部保存的是 epoch 秒和纳秒部分。


1. Instant 和其他时间类的区别

Java 8 有几个常见时间类:

表示 是否带时区
LocalDate 日期
LocalTime 时间
LocalDateTime 日期+时间
ZonedDateTime 日期+时间+时区
Instant 时间线上的一个点 ❌(固定UTC)

例如:

中国时间:

2026-07-26 18:00:00

转换成 UTC:

2026-07-26T10:00:00Z

这两个实际上是同一个瞬间。

Instant 只关心:

这个事件发生在哪一刻

不关心:

当地显示几点

2. 创建 Instant

2.1 获取当前时间

最常用:

Instant now = Instant.now();

System.out.println(now);

输出:

2026-07-26T02:35:20.123Z

注意:

这里显示的是 UTC 时间。

你的电脑如果是中国时区:

北京时间 10:35

UTC时间 02:35

所以会相差8小时。


3. 根据时间戳创建 Instant

秒级时间戳

例如:

Unix时间:

1720000000
Instant instant =
        Instant.ofEpochSecond(1720000000);

毫秒级时间戳

Java 中更常见:

long millis = System.currentTimeMillis();

Instant instant =
        Instant.ofEpochMilli(millis);

例如:

System.out.println(
    Instant.ofEpochMilli(
        System.currentTimeMillis()
    )
);

4. Instant 转时间戳

转秒

Instant now = Instant.now();

long seconds =
        now.getEpochSecond();

例如:

1720000000

转毫秒

开发中更常用:

long millis =
        now.toEpochMilli();

等价于:

System.currentTimeMillis()

5. Instant 时间计算

Instant 本身不可变。

例如:

增加一天:

Instant now = Instant.now();

Instant tomorrow =
        now.plusSeconds(86400);

减少时间:

Instant before =
        now.minusSeconds(60);

表示:

一分钟之前。


更推荐:

import java.time.Duration;


Instant start = Instant.now();


// 执行业务


Instant end = Instant.now();


Duration duration =
        Duration.between(start,end);


System.out.println(
    duration.toMillis()
);

输出:

执行耗时(ms)

这在性能测试非常常见。


6. Instant 比较时间

因为 Instant 实现了 Comparable:

可以直接比较:

Instant a =
        Instant.parse(
        "2026-01-01T00:00:00Z"
        );


Instant b =
        Instant.now();


System.out.println(
        a.isBefore(b)
);

结果:

true

方法:

isBefore()

isAfter()

equals()

7. Instant 和 Date 转换

以前 Java 使用:

java.util.Date

现在推荐:

java.time.Instant

Date -> Instant

Date date = new Date();


Instant instant =
        date.toInstant();

Instant -> Date

Instant instant =
        Instant.now();


Date date =
        Date.from(instant);

8. Instant 和 LocalDateTime转换(重点)

很多人容易混淆。

Instant 转 LocalDateTime

必须指定时区:

Instant instant =
        Instant.now();


LocalDateTime time =
        LocalDateTime.ofInstant(
                instant,
                ZoneId.systemDefault()
        );

例如:

服务器:

UTC

用户:

Asia/Shanghai

显示时间不同。


LocalDateTime 转 Instant

也需要时区:

LocalDateTime local =
        LocalDateTime.now();


Instant instant =
        local.atZone(
            ZoneId.systemDefault()
        )
        .toInstant();

原因:

LocalDateTime:

2026-07-26 10:00

不知道:

哪个地区?

可能是:

中国10点
美国10点
日本10点

对应不同 Instant。


9. Spring Boot 中常见用途

你的项目里面 JWT 就很适合。

比如:

JWT过期时间

Instant expiration =
        Instant.now()
        .plusSeconds(3600);

表示:

当前时间 + 1小时。


Redis TTL计算

例如:

JWT:

过期时间:
2026-07-26T12:00:00Z

当前:

2026-07-26T10:00:00Z

计算剩余:

Duration duration =
        Duration.between(
            Instant.now(),
            expiration
        );


long seconds =
        duration.getSeconds();

然后:

redisTemplate.expire(
    key,
    seconds,
    TimeUnit.SECONDS
);

10. Instant.parse()

解析 ISO-8601 格式:

Instant instant =
    Instant.parse(
        "2026-07-26T10:00:00Z"
    );

格式:

yyyy-MM-ddTHH:mm:ssZ

其中:

Z

代表:

UTC

11. Instant 的几个常用方法总结

方法 作用
Instant.now() 当前时间
ofEpochSecond() 秒时间戳转Instant
ofEpochMilli() 毫秒时间戳转Instant
toEpochMilli() Instant转毫秒
getEpochSecond() Instant转秒
plusSeconds() 增加秒
minusSeconds() 减少秒
isBefore() 是否之前
isAfter() 是否之后
parse() 字符串解析

可以这样理解:

LocalDateTime
    ↓
给人看的时间

2026-07-26 18:00


Instant
    ↓
给机器看的时间

2026-07-26T10:00:00Z

所以:

  • 用户界面展示 → LocalDateTime
  • 数据库存储 → Instant
  • 日志记录 → Instant
  • JWT过期 → Instant
  • 时间比较 → Instant

在后端开发中,Instant 基本就是现代 Java 替代 Date 的核心时间类型。

以下为需要外部引入的类

ObjectMapper JSON转换工具

ObjectMapper 是 Jackson 提供的核心类,用于 Java 对象和 JSON 数据之间的转换

你可以把它理解为:

ObjectMapper = Java对象 ↔ JSON 的转换工具。

在 Spring Boot 中,Jackson 默认已经集成,所以你经常会看到:

@Autowired
private ObjectMapper objectMapper;

一、ObjectMapper 的两个核心方向

整体分为两类:

Java对象
   |
   | 序列化
   ↓
 JSON字符串


 JSON字符串
   |
   | 反序列化
   ↓
Java对象

二、writeValueAsString()

作用

Java对象 → JSON字符串

这是你当前项目用到的方法。

方法:

String writeValueAsString(Object value)

例如:

DTO:

@Data
public class ApplicationDTO {

    private String name;

    private Integer duration;

    private Boolean active;
}

对象:

ApplicationDTO app = new ApplicationDTO();

app.setName("Chrome");
app.setDuration(3600);
app.setActive(true);

转换:

String json =
    objectMapper.writeValueAsString(app);

结果:

{
    "name":"Chrome",
    "duration":3600,
    "active":true
}

你的 Redis:

redisTemplate.opsForHash()
        .put(
            key,
            app.getName(),
            json
        );

实际保存:

Chrome
 |
 {"name":"Chrome","duration":3600,"active":true}

三、readValue()

作用

JSON字符串 → Java对象

对应:

writeValueAsString()

的方法。

形式:

<T> T readValue(
    String content,
    Class<T> valueType
)

例如:

Redis取出:

String json =
"{\"name\":\"Chrome\",\"duration\":3600}";

转换:

ApplicationDTO app =
    objectMapper.readValue(
        json,
        ApplicationDTO.class
    );

结果:

ApplicationDTO对象

name = Chrome
duration = 3600

四、writeValue()

作用

对象写入各种输出目标。

和:

writeValueAsString()

类似。

区别:

方法 目标
writeValueAsString 返回字符串
writeValue 写入文件、流等

写入文件

例如:

objectMapper.writeValue(
    new File("user.json"),
    user
);

生成:

user.json

内容:

{
"name":"Tom",
"age":20
}

写入输出流

例如:

objectMapper.writeValue(
    outputStream,
    user
);

常用于:

  • HTTP响应
  • 文件传输

五、readValue()读取不同类型

1. 普通对象

User user =
objectMapper.readValue(
    json,
    User.class
);

2. List集合

这是很常用的。

JSON:

[
 {
  "name":"Chrome"
 },
 {
  "name":"IDEA"
 }
]

不能:

objectMapper.readValue(
    json,
    List.class
);

因为泛型丢失。

应该:

List<ApplicationDTO> list =
    objectMapper.readValue(
        json,
        new TypeReference<List<ApplicationDTO>>() {}
    );

为什么?

因为:

List<ApplicationDTO>

运行时会被擦除:

变成:

List

Jackson不知道里面是什么对象。


六、convertValue()

作用

对象类型转换。

例如:

Map:

Map<String,Object> map = new HashMap<>();

map.put("name","Tom");
map.put("age",20);

转换:

User user =
    objectMapper.convertValue(
        map,
        User.class
    );

结果:

User{name="Tom", age=20}

常用于:

  • DTO转换
  • VO转换
  • Map转对象

例如:

UserDTO dto =
objectMapper.convertValue(
    entity,
    UserDTO.class
);

七、readTree()

作用

JSON字符串 → JsonNode树结构

适合:

不知道 JSON 结构,只想读取部分字段。

例如:

JSON:

{
"name":"Chrome",
"duration":3600
}

代码:

JsonNode node =
    objectMapper.readTree(json);

获取:

String name =
    node.get("name")
        .asText();

结果:

Chrome

比如:

第三方接口返回:

{
"code":200,
"data":{
    "username":"Tom"
}
}

你只需要:

node.get("data")
    .get("username");

不用创建实体类。


八、treeToValue()

readTree() 相反。

JsonNode:

JsonNode node;

转对象:

User user =
objectMapper.treeToValue(
    node,
    User.class
);

流程:

JSON
 |
readTree()
 |
JsonNode
 |
treeToValue()
 |
Java对象

九、configure()

配置 ObjectMapper 行为。

忽略未知字段

例如:

JSON:

{
"name":"Tom",
"age":20,
"address":"Tokyo"
}

Java:

class User{
    String name;
}

默认:

报错。

配置:

objectMapper.configure(
    DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
    false
);

结果:

忽略:

address

十、常见方法总结

方法 作用 使用场景
writeValueAsString() 对象→JSON字符串 Redis、接口返回
readValue() JSON→对象 读取缓存、接口解析
writeValue() 对象写文件/流 文件、响应
convertValue() 对象类型转换 DTO转换
readTree() JSON→树 动态JSON
treeToValue() 树→对象 JsonNode恢复对象
configure() 修改配置 格式控制
posted @ 2026-07-02 17:46  畅畅c  阅读(8)  评论(0)    收藏  举报