java工具类

我爱海鲸 2025-10-11 16:04:28 暂无标签

简介hutool、字符串工具、gson、电话脱敏、时间校验、springboot项目中读取resource中的文本

GsonUtil 工具类

我一直以为fastjson的坑是最多的,今天用了一下Gson,它的坑也不少,Long类型在反序列化的时候会将数据转化为科学计数法。

2024-11-06 start:

/**
 * @author haijin
 * @description: 文本解析工具类,提供从字符串中提取指定内容的常用方法
 * @date 2024/10/23 16:50
 */
public class TextUtil {

    /**
     * 获取从第一个匹配的起始关键字之后,到多个结束关键字中最早出现的那个之间的最短子串(正向查找)。
     * 如果未找到起始关键字或所有结束关键字,则返回原字符串。
     *
     * @param str        源字符串
     * @param first      起始关键字
     * @param secondKeys 多个可能的结束关键字
     * @return 提取的子字符串
     */
    public static String getShortStringBetweenKeys(String str, String first, String[] secondKeys) {
        return getShortStringBetweenKeys(str, first, secondKeys, true);
    }

    /**
     * 获取从最后一个匹配的起始关键字之后,到多个结束关键字中最早出现的那个之间的最短子串(逆向查找起始关键字)。
     * 常用于匹配最近一次出现的起始标记。
     *
     * @param str        源字符串
     * @param first      起始关键字
     * @param secondKeys 多个可能的结束关键字
     * @return 提取的子字符串
     */
    public static String getShortStringBetweenLastKeys(String str, String first, String[] secondKeys) {
        return getShortStringBetweenKeys(str, first, secondKeys, false);
    }

    /**
     * 获取从起始关键字之后,到多个结束关键字中最早出现的那个之间的最短子串。
     * 可选择从前往后(asc=true)或从后往前(asc=false)查找起始关键字。
     *
     * @param str        源字符串
     * @param first      起始关键字
     * @param secondKeys 多个可能的结束关键字
     * @param asc        true表示正向查找起始关键字,false表示逆向查找
     * @return 提取的子字符串
     */
    public static String getShortStringBetweenKeys(String str, String first, String[] secondKeys, boolean asc) {
        if (str != null && first != null && secondKeys != null) {
            int firstIndex = -1;
            if (asc) {
                firstIndex = str.indexOf(first);
            } else {
                firstIndex = str.lastIndexOf(first);
            }
            if (firstIndex != -1) {
                int secondIndex = -1;
                firstIndex += first.length(); // 移动到起始关键字之后
                for (int i = 0; i < secondKeys.length; i++) {
                    int index = str.indexOf(secondKeys[i], firstIndex);
                    if (index != -1 && (secondIndex == -1 || index < secondIndex)) {
                        secondIndex = index; // 找到最早出现的结束关键字
                    }
                }
                if (secondIndex == -1) {
                    secondIndex = str.length(); // 如果没有结束关键字,则截取到字符串末尾
                }
                str = str.substring(firstIndex, secondIndex);
            }
        }
        return str;
    }

    /**
     * 获取从第一个匹配的起始关键字之后,到第一个匹配的结束关键字之间的子串。
     * 如果未找到起始关键字,则返回空字符串;如果未找到结束关键字,则截取到字符串末尾。
     *
     * @param str    源字符串
     * @param first  起始关键字
     * @param second 结束关键字
     * @return 提取的子字符串
     */
    public static String getStringBetweenKeys(String str, String first, String second) {
        if (str != null && first != null && second != null) {
            int firstIndex = str.indexOf(first);
            if (firstIndex != -1) {
                firstIndex += first.length();
                int secondIndex = str.indexOf(second, firstIndex);
                if (secondIndex == -1) {
                    secondIndex = str.length();
                }
                str = str.substring(firstIndex, secondIndex);
            } else {
                str = "";
            }
        }
        return str;
    }

    /**
     * 获取从最后一个匹配的起始关键字之后,到下一个结束关键字之间的子串。
     * 特别适用于起始和结束关键字相同的情况(如引号、括号等)。
     *
     * @param str    源字符串
     * @param first  起始关键字
     * @param second 结束关键字
     * @return 提取的子字符串
     */
    public static String getStringBetweenLastKeys(String str, String first, String second) {
        if (str != null && first != null && second != null) {
            int firstIndex = str.lastIndexOf(first);
            // 如果起始和结束关键字相同,需避免匹配到同一个位置
            if (firstIndex != -1 && first.equals(second)) {
                firstIndex = str.lastIndexOf(first, firstIndex - first.length());
            }
            if (firstIndex != -1) {
                firstIndex += first.length();
                int secondIndex = str.indexOf(second, firstIndex);
                if (secondIndex == -1) {
                    secondIndex = str.length();
                }
                str = str.substring(firstIndex, secondIndex);
            }
        }
        return str;
    }

    /**
     * 获取从指定关键字第一次出现之后的所有内容(从字符串开头查找)。
     * 如果关键字不存在,则行为未定义(可能抛出异常)。
     *
     * @param str 源字符串
     * @param key 关键字
     * @return 关键字之后的子字符串
     */
    public static String getStringAfterKey(String str, String key) {
        return getStringAfterKey(str, key, 0);
    }

    /**
     * 获取从指定关键字在给定索引后第一次出现之后的所有内容。
     * 常用于查找多次出现的关键字。
     *
     * @param str       源字符串
     * @param key       关键字
     * @param fromIndex 开始查找的索引位置
     * @return 关键字之后的子字符串
     */
    public static String getStringAfterKey(String str, String key, int fromIndex) {
        if (str != null && key != null) {
            str = str.substring(str.indexOf(key, fromIndex) + key.length());
        }
        return str;
    }

    /**
     * 获取从最后一个匹配的关键字之后的所有内容。
     *
     * @param str 源字符串
     * @param key 关键字
     * @return 最后一个关键字之后的子字符串
     */
    public static String getStringAfterLastKey(String str, String key) {
        if (str != null && key != null) {
            str = str.substring(str.lastIndexOf(key) + key.length());
        }
        return str;
    }

    /**
     * 获取从字符串开头到第一个匹配的关键字之前的内容。
     * 如果关键字不存在,则返回原字符串。
     *
     * @param str 源字符串
     * @param key 关键字
     * @return 关键字之前的子字符串
     */
    public static String getStringBeforeKey(String str, String key) {
        if (str != null && key != null && str.indexOf(key) != -1) {
            str = str.substring(0, str.indexOf(key));
        }
        return str;
    }

    /**
     * 获取从字符串开头到多个关键字中最早出现的那个之前的内容。
     * 常用于提取直到某个分隔符之前的内容。
     *
     * @param str   源字符串
     * @param keys  多个可能的关键字
     * @return 第一个关键字之前的所有内容
     */
    public static String getStringBeforeKeys(String str, String... keys) {
        int firstIndex = -1;
        for (int i = 0; i < keys.length; i++) {
            int index = str.indexOf(keys[i]);
            if (index != -1 && (firstIndex == -1 || index < firstIndex)) {
                firstIndex = index;
            }
        }
        if (firstIndex == -1) {
            firstIndex = str.length();
        }
        str = str.substring(0, firstIndex);
        return str;
    }

    /**
     * 获取从字符串开头到最后一个匹配的关键字之前的内容。
     *
     * @param str 源字符串
     * @param key 关键字
     * @return 最后一个关键字之前的内容
     */
    public static String getStringBeforeLastKey(String str, String key) {
        if (str != null && key != null && str.lastIndexOf(key) != -1) {
            str = str.substring(0, str.lastIndexOf(key)); 
        }
        return str;
    }
}

电话脱敏:

   /**
     * 电话脱敏
     * @param phoneNumber 电话号码
     * @return ignore
     */
    private String maskPhoneNumber(String phoneNumber) {
        if (phoneNumber == null || phoneNumber.length() < 8) {
            return phoneNumber;
        }
        return phoneNumber.substring(0, 3) + "****" + phoneNumber.substring(7);
    }

end

2025-03-19 start:

将一个时间片分片(每10分钟一个分片)

 /**
     * 将时间段拆分为 10 分钟一段的时间片
     *
     * @param startTimeStr 开始时间字符串(格式:yyyy-MM-dd HH:mm:ss)
     * @param endTimeStr   结束时间字符串(格式:yyyy-MM-dd HH:mm:ss)
     * @return 拆分后的时间片列表,每个时间片是一个 Map
     */
    public static List<Map<String, String>> splitTimeRange(String startTimeStr, String endTimeStr) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 将字符串解析为 LocalDateTime
        LocalDateTime startTime = LocalDateTime.parse(startTimeStr, formatter);
        LocalDateTime endTime = LocalDateTime.parse(endTimeStr, formatter);
        List<Map<String, String>> timeRanges = new ArrayList<>();
        // 如果开始时间大于结束时间,直接返回空列表
        if (startTime.isAfter(endTime)) {
            throw new IllegalArgumentException("开始时间不能晚于结束时间");
        }
        LocalDateTime currentStart = startTime;
        // 循环拆分时间段
        while (currentStart.isBefore(endTime)) {
            LocalDateTime currentEnd = currentStart.plusMinutes(10);
            if (currentEnd.isAfter(endTime)) {
                currentEnd = endTime;
            }
            Map<String, String> timeRange = new HashMap<>();
            timeRange.put("startTime", currentStart.format(formatter));
            timeRange.put("endTime", currentEnd.format(formatter));

            timeRanges.add(timeRange);

            currentStart = currentEnd;
        }
        return timeRanges;
    }

 

时间校验:

      // 定义时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 解析输入的时间字符串为LocalDateTime对象
        LocalDateTime startTimeDate = LocalDateTime.parse(startTime, formatter);
        LocalDateTime endTimeDate = LocalDateTime.parse(endTime, formatter);
        // 判断开始时间是否小于结束时间
        if (startTimeDate.isAfter(endTimeDate) || startTimeDate.isEqual(endTimeDate)) {
            throw new Exception("开始时间要小于结束时间");
        }
        // 计算时间差
        Duration duration = Duration.between(startTimeDate, endTimeDate);
        // 判断是否超过一个小时
        if (duration.getSeconds() > 3600) {
            throw new Exception("输入的时间不能超过一个小时");
        }

end

2025-10-11 start:

springboot项目中读取resource中的文本:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;

public class TextLoader {
    public static String loadLargeString() throws Exception {
        Path path = Paths.get(Objects.requireNonNull(
                TextLoader.class.getClassLoader().getResource("large_text.txt")
        ).toURI());
        return Files.readString(path);
    }
}

end

你好:我的2025