Java编程核心问题解析与实战指南

第1章 字符串处理与数学运算

1.1 字符统计与转换

统计重复字符数量

通过哈希表实现O(n)时间复杂度的字符频率统计:

  1. public static Map<Character, Integer> countChars(String str) {
  2. Map<Character, Integer> map = new HashMap<>();
  3. for (char c : str.toCharArray()) {
  4. map.put(c, map.getOrDefault(c, 0) + 1);
  5. }
  6. return map;
  7. }

寻找首个非重复字符

结合LinkedHashMap保持插入顺序的特性:

  1. public static char firstNonRepeating(String str) {
  2. LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
  3. for (char c : str.toCharArray()) {
  4. map.put(c, map.getOrDefault(c, 0) + 1);
  5. }
  6. for (Map.Entry<Character, Integer> entry : map.entrySet()) {
  7. if (entry.getValue() == 1) return entry.getKey();
  8. }
  9. return '\0';
  10. }

字符串反转技术

三种实现方式对比:

  1. 字符数组交换(原地反转):

    1. public static String reverse(String str) {
    2. char[] chars = str.toCharArray();
    3. for (int i = 0; i < chars.length/2; i++) {
    4. char temp = chars[i];
    5. chars[i] = chars[chars.length-1-i];
    6. chars[chars.length-1-i] = temp;
    7. }
    8. return new String(chars);
    9. }
  2. StringBuilder反转(推荐):

    1. public static String reverseSB(String str) {
    2. return new StringBuilder(str).reverse().toString();
    3. }
  3. 递归实现(仅作演示):

    1. public static String reverseRecursive(String str) {
    2. if (str.isEmpty()) return str;
    3. return reverseRecursive(str.substring(1)) + str.charAt(0);
    4. }

1.2 数字处理与转换

大数安全运算

处理int/long溢出场景的加法实现:

  1. public static long safeAdd(long a, long b) {
  2. if (b > 0 ? a > Long.MAX_VALUE - b : a < Long.MIN_VALUE - b) {
  3. throw new ArithmeticException("Long overflow");
  4. }
  5. return a + b;
  6. }

进制转换技巧

解析非十进制字符串的完整方案:

  1. public static long parseUnsigned(String s, int radix) throws NumberFormatException {
  2. if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
  3. throw new NumberFormatException("Radix out of range");
  4. }
  5. long result = 0;
  6. for (int i = 0; i < s.length(); i++) {
  7. char c = s.charAt(i);
  8. int digit = Character.digit(c, radix);
  9. if (digit == -1) {
  10. throw new NumberFormatException("Illegal digit for radix: " + c);
  11. }
  12. // 检查溢出
  13. if (result > (Long.MAX_VALUE - digit) / radix) {
  14. throw new ArithmeticException("Long overflow");
  15. }
  16. result = result * radix + digit;
  17. }
  18. return result;
  19. }

浮点数处理

判断有限浮点数的正确方法:

  1. public static boolean isFinite(double d) {
  2. return !Double.isInfinite(d) && !Double.isNaN(d);
  3. }

1.3 高级字符串操作

文本块处理(Java 15+)

多行字符串声明方式对比:

  1. // 传统方式
  2. String html = "<html>\n" +
  3. " <body>\n" +
  4. " <p>Hello, world</p>\n" +
  5. " </body>\n" +
  6. "</html>\n";
  7. // 文本块方式
  8. String htmlBlock = """
  9. <html>
  10. <body>
  11. <p>Hello, world</p>
  12. </body>
  13. </html>
  14. """;

字符串缩进控制

文本块缩进处理方案:

  1. String indented = """
  2. Hello
  3. World
  4. """.stripIndent() // 移除共同前导空白
  5. .indent(4); // 添加指定缩进

紧凑数字格式化

金融场景数字格式化示例:

  1. public static String formatCurrency(double amount) {
  2. NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
  3. currencyFormat.setMinimumFractionDigits(2);
  4. currencyFormat.setMaximumFractionDigits(2);
  5. return currencyFormat.format(amount);
  6. }

第2章 对象操作与不可变性

2.1 空引用检查

函数式与命令式风格对比:

  1. // 命令式风格
  2. public static boolean isNullCommand(Object obj) {
  3. if (obj == null) {
  4. System.out.println("Object is null");
  5. return true;
  6. }
  7. return false;
  8. }
  9. // 函数式风格
  10. public static Optional<Object> checkNullFunctional(Object obj) {
  11. return Optional.ofNullable(obj)
  12. .map(o -> {
  13. System.out.println("Object exists");
  14. return o;
  15. });
  16. }

2.2 不可变对象设计

创建不可变类的完整方案:

  1. public final class ImmutablePoint {
  2. private final int x;
  3. private final int y;
  4. public ImmutablePoint(int x, int y) {
  5. this.x = x;
  6. this.y = y;
  7. }
  8. public int getX() { return x; }
  9. public int getY() { return y; }
  10. // 防御性拷贝示例
  11. public ImmutablePoint translate(int dx, int dy) {
  12. return new ImmutablePoint(x + dx, y + dy);
  13. }
  14. }

2.3 Switch表达式进阶

Java 12+增强版Switch表达式:

  1. // 传统Switch
  2. String dayType;
  3. switch (day) {
  4. case "MON": case "TUE": case "WED": case "THU": case "FRI":
  5. dayType = "Weekday";
  6. break;
  7. case "SAT": case "SUN":
  8. dayType = "Weekend";
  9. break;
  10. default:
  11. dayType = "Invalid";
  12. }
  13. // Switch表达式
  14. String dayTypeExpr = switch (day) {
  15. case "MON", "TUE", "WED", "THU", "FRI" -> "Weekday";
  16. case "SAT", "SUN" -> "Weekend";
  17. default -> throw new IllegalArgumentException("Invalid day: " + day);
  18. };

2.4 数值类型转换

安全转换long到int的方案:

  1. public static int safeLongToInt(long value) {
  2. if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
  3. throw new ArithmeticException("Value out of int range");
  4. }
  5. return (int) value;
  6. }

性能优化最佳实践

  1. 字符串拼接优化

    • 循环中使用StringBuilder而非”+”操作符
    • Java 9+的String.repeat()替代手动循环
  2. 大数运算优化

    • 使用BigInteger进行超大整数运算
    • 考虑Karatsuba算法优化大数乘法
  3. 对象创建优化

    • 避免在循环中创建对象
    • 使用对象池模式重用对象
  4. 正则表达式优化

    • 预编译Pattern对象
    • 避免使用捕获组当不需要时

常见问题解决方案

  1. 字符串包含子串检查

    1. public static boolean containsIgnoreCase(String source, String target) {
    2. return source.toLowerCase().contains(target.toLowerCase());
    3. }
  2. 变位词检测

    1. public static boolean isAnagram(String s1, String s2) {
    2. if (s1.length() != s2.length()) return false;
    3. char[] c1 = s1.toCharArray();
    4. char[] c2 = s2.toCharArray();
    5. Arrays.sort(c1);
    6. Arrays.sort(c2);
    7. return Arrays.equals(c1, c2);
    8. }
  3. 最长公共前缀

    1. public static String longestCommonPrefix(String[] strs) {
    2. if (strs == null || strs.length == 0) return "";
    3. Arrays.sort(strs);
    4. String first = strs[0];
    5. String last = strs[strs.length-1];
    6. int i = 0;
    7. while (i < first.length() && i < last.length()
    8. && first.charAt(i) == last.charAt(i)) {
    9. i++;
    10. }
    11. return first.substring(0, i);
    12. }

本文系统梳理了Java编程中字符串处理、数字运算和对象操作三大核心领域的典型问题,提供了经过生产环境验证的解决方案。通过掌握这些技术要点,开发者可以显著提升代码质量,有效避免常见陷阱,特别是在处理边界条件和性能优化方面获得实质性提升。建议结合具体业务场景选择最适合的实现方案,并在关键路径代码中添加充分的单元测试。