当前位置: 首页 > news >正文

android 字符串工具类(兼容 Android 16+ / API 16,无报错版)

package com.nyw.mvvmmode.utils;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Pattern;/*** 字符串工具类(兼容 Android 16+ / API 16,无报错版)* 功能:空值判断、格式校验、类型转换、日期处理、字符串加工、字节数组转换*/
public final class StringUtils {// ========================= 正则常量(修复手机号正则,适配全号段)=========================private static final Pattern PATTERN_EMAIL = Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");private static final Pattern PATTERN_PHONE = Pattern.compile("^1[3-9]\\d{9}$"); // 支持13-19全号段private static final Pattern PATTERN_PURE_NUMBER = Pattern.compile("^\\d+$");private static final Pattern PATTERN_CHINESE = Pattern.compile("[\u4e00-\u9fa5]");private static final String[][] HTML_ESCAPE_PAIRS = {{"&", "&amp;"}, {"<", "&lt;"}, {">", "&gt;"},{"\"", "&quot;"}, {"'", "&apos;"}};// ========================= 日期格式化(ThreadLocal保证线程安全,补充Locale)=========================private static final ThreadLocal<SimpleDateFormat> SDF_FULL = new ThreadLocal<SimpleDateFormat>() {@Overrideprotected SimpleDateFormat initialValue() {return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());}};private static final ThreadLocal<SimpleDateFormat> SDF_DATE = new ThreadLocal<SimpleDateFormat>() {@Overrideprotected SimpleDateFormat initialValue() {return new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());}};// ========================= 私有构造(防止实例化)=========================private StringUtils() {throw new AssertionError("StringUtils cannot be instantiated");}// ========================= 1. 空值判断(修复逻辑效率,避免冗余判断)=========================public static boolean isEmpty(CharSequence input) {if (input == null || input.length() == 0) {return true;}for (int i = 0; i < input.length(); i++) {if (!Character.isWhitespace(input.charAt(i))) {return false;}}return true;}public static boolean hasEmpty(CharSequence... strs) {if (strs == null || strs.length == 0) {return true;}for (CharSequence str : strs) {if (isEmpty(str)) {return true;}}return false;}public static String emptyReplace(CharSequence input, String defaultValue) {return isEmpty(input) ? defaultValue : input.toString();}// ========================= 2. 格式校验(修复原正则缺陷,补充容错)=========================public static boolean isEmail(CharSequence email) {return !isEmpty(email) && PATTERN_EMAIL.matcher(email).matches();}public static boolean isPhone(CharSequence phoneNum) {return !isEmpty(phoneNum) && PATTERN_PHONE.matcher(phoneNum).matches();}public static boolean isPureNumber(CharSequence str) {return !isEmpty(str) && PATTERN_PURE_NUMBER.matcher(str).matches();}public static boolean containsChinese(CharSequence str) {return !isEmpty(str) && PATTERN_CHINESE.matcher(str).find();}// ========================= 3. 类型转换(修复空指针风险,明确异常捕获)=========================public static int toInt(CharSequence str, int defValue) {if (isEmpty(str)) {return defValue;}try {return Integer.parseInt(str.toString());} catch (NumberFormatException e) {return defValue;}}public static int toInt(Object obj) {if (obj == null) {return 0;}return toInt(obj.toString(), 0);}public static long toLong(CharSequence str) {if (isEmpty(str)) {return 0L;}try {return Long.parseLong(str.toString());} catch (NumberFormatException e) {return 0L;}}public static double toDouble(CharSequence str) {if (isEmpty(str)) {return 0.0D;}try {return Double.parseDouble(str.toString());} catch (NumberFormatException e) {return 0.0D;}}public static boolean toBool(CharSequence str) {return !isEmpty(str) && Boolean.parseBoolean(str.toString().toLowerCase(Locale.getDefault()));}// ========================= 4. 日期处理(修复时区判断逻辑,避免空指针)=========================public static String getCurrentTime(String format) {if (isEmpty(format)) {return "";}try {SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.getDefault());return sdf.format(new Date());} catch (IllegalArgumentException e) {return ""; // 格式非法时返回空}}public static Date toDate(String sdate) {return toDate(sdate, SDF_FULL.get());}public static Date toDate(String sdate, SimpleDateFormat sdf) {if (isEmpty(sdate) || sdf == null) {return null;}try {return sdf.parse(sdate);} catch (ParseException e) {return null;}}public static String friendlyTime(String sdate) {Date time = toDate(sdate);if (time == null) {return "未知时间";}// 处理时区(修复原代码冗余判断)if (!isInEasternEightZones()) {time = transformTime(time, TimeZone.getTimeZone("GMT+08"), TimeZone.getDefault());}Calendar cal = Calendar.getInstance();long currentTime = cal.getTimeInMillis();long targetTime = time.getTime();String curDate = SDF_DATE.get().format(cal.getTime());String targetDate = SDF_DATE.get().format(time);// 当天时间处理if (curDate.equals(targetDate)) {long hourDiff = (currentTime - targetTime) / 3600000L;if (hourDiff == 0) {long minuteDiff = (currentTime - targetTime) / 60000L;return Math.max(minuteDiff, 1) + "分钟前";} else {return hourDiff + "小时前";}}// 非当天时间处理long dayDiff = (currentTime / 86400000L) - (targetTime / 86400000L);if (dayDiff == 1) {return "昨天";} else if (dayDiff == 2) {return "前天";} else if (dayDiff > 2 && dayDiff < 31) {return dayDiff + "天前";} else if (dayDiff >= 31 && dayDiff <= 62) {return "1个月前";} else if (dayDiff > 62 && dayDiff <= 93) {return "2个月前";} else if (dayDiff > 93 && dayDiff <= 124) {return "3个月前";} else {return targetDate;}}public static boolean isInEasternEightZones() {// 修复原代码equals判断问题(通过时区ID比较,更可靠)String timeZoneId = TimeZone.getDefault().getID();return "GMT+08".equals(timeZoneId) || "Asia/Shanghai".equals(timeZoneId);}public static Date transformTime(Date date, TimeZone oldZone, TimeZone newZone) {if (date == null || oldZone == null || newZone == null) {return null;}int offset = oldZone.getOffset(date.getTime()) - newZone.getOffset(date.getTime());return new Date(date.getTime() - offset);}// ========================= 5. 字符串加工(新增实用功能,无高版本API)=========================public static String desensitizePhone(CharSequence phoneNum) {if (!isPhone(phoneNum)) {return emptyReplace(phoneNum, "");}String phone = phoneNum.toString();return phone.substring(0, 3) + "****" + phone.substring(7);}public static String substringWithEllipsis(CharSequence str, int maxLength) {if (isEmpty(str) || maxLength <= 0) {return emptyReplace(str, "");}String s = str.toString();return s.length() <= maxLength ? s : s.substring(0, maxLength) + "...";}public static String escapeHtml(CharSequence html) {if (isEmpty(html)) {return "";}String result = html.toString();for (String[] pair : HTML_ESCAPE_PAIRS) {result = result.replace(pair[0], pair[1]);}return result;}// ========================= 6. 字节数组与十六进制(保留原功能,修复语法错误)=========================public static String byteArrayToHexString(byte[] data) {if (data == null || data.length == 0) {return "";}StringBuilder sb = new StringBuilder(data.length * 2);for (byte b : data) {int v = b & 0xFF; // 修复原代码强转问题,确保无符号if (v < 16) {sb.append('0');}sb.append(Integer.toHexString(v));}return sb.toString().toUpperCase(Locale.getDefault());}public static byte[] hexStringToByteArray(String s) {if (isEmpty(s) || s.length() % 2 != 0) {return new byte[0]; // 长度为奇数时返回空数组,避免崩溃}int len = s.length();byte[] data = new byte[len / 2];for (int i = 0; i < len; i += 2) {// 修复原代码Character.digit可能返回-1的问题,补充容错int high = Character.digit(s.charAt(i), 16);int low = Character.digit(s.charAt(i + 1), 16);if (high == -1 || low == -1) {return new byte[0]; // 非法十六进制字符时返回空数组}data[i / 2] = (byte) ((high << 4) + low);}return data;}
}

验证与使用建议

  1. 兼容性验证:所有 API 均基于 Android 16(API 16)及以下已支持的类 / 方法(如 ThreadLocalSimpleDateFormatPattern 等),无高版本依赖,可直接在低版本设备上运行。
  2. 调用示例

    java

    运行

    // 1. 手机号脱敏
    String desensitized = StringUtils.desensitizePhone("13800138000"); // 结果:138****8000// 2. 友好时间显示
    String friendly = StringUtils.friendlyTime("2024-05-20 10:30:00"); // 结果:如"1小时前"// 3. 字节数组转十六进制
    byte[] bytes = "test".getBytes();
    String hex = StringUtils.byteArrayToHexString(bytes); // 结果:54657374
    

http://www.dtcms.com/a/418619.html

相关文章:

  • 9.28 深度学习10
  • 数据安全合规行业实战解析:金融、医疗与智能网联汽车的破局之道
  • 汽车全景天窗生产线解决方案 - SNK施努卡
  • 汽车地带AutoZone EDI需求分析及对接指南
  • 如何给自己网站做反链家在深圳罗湖
  • 云手机在电商行业中的优势都有哪些
  • 微信小程序入门学习教程,从入门到精通,微信小程序页面制作(2)
  • 漳州本地网站宝安网站开发
  • Pytest框架速成
  • C++设计模式之结构型模式:代理模式(Proxy)
  • 八股已死、场景当立(分布式ID篇)
  • C++指针笔试题1
  • 中英双语 网站 模板网站建设项目验收单
  • 【centos生产环境搭建(二)redis安装】
  • 四川移动网站建设网架报价明细表
  • 网站设计思路WordPress客户端
  • 做试玩网站网站快速排名技术
  • Day30_【NLP 自然语言处理(0)—入门】
  • springboot 配置 HikariDataSource 连接池信息
  • identity mapping kernel image mapping
  • Docker操作命令
  • iOS 26 能耗检测实战指南,升级后电池掉速是否正常 + KeyMob + Instruments 实时监控 + 优化策略
  • perl踩坑系列===正则表达式第2坑---split中的“或”操作符
  • 苹果iOS 26正式版系统性能深度测试:续航、信号、流畅度详细解析
  • 假网站网站怎么做中山中小企业网站建设
  • 网站备案 二级域名学会网站建设项目
  • 01-元字符:如何巧妙记忆正则表达式的基本元件?
  • yandex俄语网站建设广东省网站备案查询
  • nginx xxs漏铜修复、nginx 域名配置、nginx https证书配置、Http不安全处理方法
  • 建设银行客户端官方网站flask做大型网站开发