第1章 字符串处理与数学运算
1.1 字符统计与转换
统计重复字符数量
通过哈希表实现O(n)时间复杂度的字符频率统计:
public static Map<Character, Integer> countChars(String str) {Map<Character, Integer> map = new HashMap<>();for (char c : str.toCharArray()) {map.put(c, map.getOrDefault(c, 0) + 1);}return map;}
寻找首个非重复字符
结合LinkedHashMap保持插入顺序的特性:
public static char firstNonRepeating(String str) {LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();for (char c : str.toCharArray()) {map.put(c, map.getOrDefault(c, 0) + 1);}for (Map.Entry<Character, Integer> entry : map.entrySet()) {if (entry.getValue() == 1) return entry.getKey();}return '\0';}
字符串反转技术
三种实现方式对比:
-
字符数组交换(原地反转):
public static String reverse(String str) {char[] chars = str.toCharArray();for (int i = 0; i < chars.length/2; i++) {char temp = chars[i];chars[i] = chars[chars.length-1-i];chars[chars.length-1-i] = temp;}return new String(chars);}
-
StringBuilder反转(推荐):
public static String reverseSB(String str) {return new StringBuilder(str).reverse().toString();}
-
递归实现(仅作演示):
public static String reverseRecursive(String str) {if (str.isEmpty()) return str;return reverseRecursive(str.substring(1)) + str.charAt(0);}
1.2 数字处理与转换
大数安全运算
处理int/long溢出场景的加法实现:
public static long safeAdd(long a, long b) {if (b > 0 ? a > Long.MAX_VALUE - b : a < Long.MIN_VALUE - b) {throw new ArithmeticException("Long overflow");}return a + b;}
进制转换技巧
解析非十进制字符串的完整方案:
public static long parseUnsigned(String s, int radix) throws NumberFormatException {if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {throw new NumberFormatException("Radix out of range");}long result = 0;for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);int digit = Character.digit(c, radix);if (digit == -1) {throw new NumberFormatException("Illegal digit for radix: " + c);}// 检查溢出if (result > (Long.MAX_VALUE - digit) / radix) {throw new ArithmeticException("Long overflow");}result = result * radix + digit;}return result;}
浮点数处理
判断有限浮点数的正确方法:
public static boolean isFinite(double d) {return !Double.isInfinite(d) && !Double.isNaN(d);}
1.3 高级字符串操作
文本块处理(Java 15+)
多行字符串声明方式对比:
// 传统方式String html = "<html>\n" +" <body>\n" +" <p>Hello, world</p>\n" +" </body>\n" +"</html>\n";// 文本块方式String htmlBlock = """<html><body><p>Hello, world</p></body></html>""";
字符串缩进控制
文本块缩进处理方案:
String indented = """HelloWorld""".stripIndent() // 移除共同前导空白.indent(4); // 添加指定缩进
紧凑数字格式化
金融场景数字格式化示例:
public static String formatCurrency(double amount) {NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();currencyFormat.setMinimumFractionDigits(2);currencyFormat.setMaximumFractionDigits(2);return currencyFormat.format(amount);}
第2章 对象操作与不可变性
2.1 空引用检查
函数式与命令式风格对比:
// 命令式风格public static boolean isNullCommand(Object obj) {if (obj == null) {System.out.println("Object is null");return true;}return false;}// 函数式风格public static Optional<Object> checkNullFunctional(Object obj) {return Optional.ofNullable(obj).map(o -> {System.out.println("Object exists");return o;});}
2.2 不可变对象设计
创建不可变类的完整方案:
public final class ImmutablePoint {private final int x;private final int y;public ImmutablePoint(int x, int y) {this.x = x;this.y = y;}public int getX() { return x; }public int getY() { return y; }// 防御性拷贝示例public ImmutablePoint translate(int dx, int dy) {return new ImmutablePoint(x + dx, y + dy);}}
2.3 Switch表达式进阶
Java 12+增强版Switch表达式:
// 传统SwitchString dayType;switch (day) {case "MON": case "TUE": case "WED": case "THU": case "FRI":dayType = "Weekday";break;case "SAT": case "SUN":dayType = "Weekend";break;default:dayType = "Invalid";}// Switch表达式String dayTypeExpr = switch (day) {case "MON", "TUE", "WED", "THU", "FRI" -> "Weekday";case "SAT", "SUN" -> "Weekend";default -> throw new IllegalArgumentException("Invalid day: " + day);};
2.4 数值类型转换
安全转换long到int的方案:
public static int safeLongToInt(long value) {if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {throw new ArithmeticException("Value out of int range");}return (int) value;}
性能优化最佳实践
-
字符串拼接优化:
- 循环中使用StringBuilder而非”+”操作符
- Java 9+的
String.repeat()替代手动循环
-
大数运算优化:
- 使用
BigInteger进行超大整数运算 - 考虑Karatsuba算法优化大数乘法
- 使用
-
对象创建优化:
- 避免在循环中创建对象
- 使用对象池模式重用对象
-
正则表达式优化:
- 预编译Pattern对象
- 避免使用捕获组当不需要时
常见问题解决方案
-
字符串包含子串检查:
public static boolean containsIgnoreCase(String source, String target) {return source.toLowerCase().contains(target.toLowerCase());}
-
变位词检测:
public static boolean isAnagram(String s1, String s2) {if (s1.length() != s2.length()) return false;char[] c1 = s1.toCharArray();char[] c2 = s2.toCharArray();Arrays.sort(c1);Arrays.sort(c2);return Arrays.equals(c1, c2);}
-
最长公共前缀:
public static String longestCommonPrefix(String[] strs) {if (strs == null || strs.length == 0) return "";Arrays.sort(strs);String first = strs[0];String last = strs[strs.length-1];int i = 0;while (i < first.length() && i < last.length()&& first.charAt(i) == last.charAt(i)) {i++;}return first.substring(0, i);}
本文系统梳理了Java编程中字符串处理、数字运算和对象操作三大核心领域的典型问题,提供了经过生产环境验证的解决方案。通过掌握这些技术要点,开发者可以显著提升代码质量,有效避免常见陷阱,特别是在处理边界条件和性能优化方面获得实质性提升。建议结合具体业务场景选择最适合的实现方案,并在关键路径代码中添加充分的单元测试。