在Java编程的世界里,String类可能是我们最早接触、使用最频繁的类之一。它看似简单,却隐藏着许多精妙的设计和实用的功能。让我们深入探索掌握String API。

一、String基础:不可变的艺术

1.1 String的不可变性

java

// String对象一旦创建就不可修改
String str = "Hello";
str.concat(" World");  // 返回新对象,原str不变
System.out.println(str);  // 输出: Hello

// 正确的方式
String newStr = str.concat(" World");
System.out.println(newStr);  // 输出: Hello World

1.2 创建String对象的多种方式

java

// 方式1:字面量创建(推荐)
String s1 = "Java";

// 方式2:构造函数
String s2 = new String("Java");

// 方式3:字符数组
char[] chars = {'J', 'a', 'v', 'a'};
String s3 = new String(chars);

// 方式4:字节数组
byte[] bytes = {74, 97, 118, 97};
String s4 = new String(bytes, StandardCharsets.UTF_8);

二、核心API详解

2.1 长度与判空

java

String text = "Hello Java";

// 获取长度
int length = text.length();  // 10

// 检查是否为空
boolean isEmpty = text.isEmpty();  // false

// 检查是否为空白(Java 11+)
boolean isBlank = text.isBlank();  // false
boolean isBlank2 = "   ".isBlank();  // true

2.2 字符串比较

java

String s1 = "Java";
String s2 = "java";
String s3 = "Java";

// equals - 区分大小写
boolean b1 = s1.equals(s2);  // false

// equalsIgnoreCase - 不区分大小写
boolean b2 = s1.equalsIgnoreCase(s2);  // true

// compareTo - 字典序比较
int result = s1.compareTo(s2);  // 负数('J' < 'j')

// contentEquals - 与任何CharSequence比较
boolean b3 = s1.contentEquals(new StringBuilder("Java"));  // true

2.3 字符串查找

java

String text = "Java Programming is fun!";

// 查找字符
int index1 = text.indexOf('a');      // 1
int index2 = text.lastIndexOf('a');  // 18

// 查找字符串
int index3 = text.indexOf("Pro");    // 5
int index4 = text.lastIndexOf("is"); // 17

// 检查前缀/后缀
boolean starts = text.startsWith("Java");  // true
boolean ends = text.endsWith("fun!");      // true

// 包含检查
boolean contains = text.contains("Program");  // true

2.4 字符串截取与分割

java

String text = "apple,banana,orange,grape";

// 截取子串
String sub1 = text.substring(6);        // "banana,orange,grape"
String sub2 = text.substring(6, 12);    // "banana"

// 分割字符串
String[] fruits = text.split(",");
// 结果: ["apple", "banana", "orange", "grape"]

// 限制分割次数
String[] limited = text.split(",", 2);
// 结果: ["apple", "banana,orange,grape"]

// 使用正则表达式分割
String complex = "a1b2c3d4";
String[] parts = complex.split("\\d");
// 结果: ["a", "b", "c", "d"]

2.5 字符串替换

java

String text = "I love Java. Java is great!";

// 简单替换
String replaced = text.replace("Java", "Python");
// 结果: "I love Python. Python is great!"

// 正则替换
String regexReplaced = text.replaceAll("\\bJava\\b", "Python");

// 替换首个匹配项
String firstReplaced = text.replaceFirst("Java", "Python");

// 字符替换
String charReplaced = text.replace('a', 'A');

2.6 大小写转换与修剪

java

String text = "  Hello Java  ";

// 大小写转换
String upper = text.toUpperCase();  // "  HELLO JAVA  "
String lower = text.toLowerCase();  // "  hello java  "

// 去除首尾空白
String trimmed = text.trim();       // "Hello Java"

// Java 11+ 增强修剪
String stripped = text.strip();          // "Hello Java"
String leadingStripped = text.stripLeading();  // "Hello Java  "
String trailingStripped = text.stripTrailing(); // "  Hello Java"

2.7 字符串连接与重复

java

// 传统连接方式
String result1 = "Hello" + " " + "World";

// 使用concat方法
String result2 = "Hello".concat(" ").concat("World");

// Java 8+ join方法
String result3 = String.join("-", "2024", "01", "15");
// 结果: "2024-01-15"

String[] words = {"Java", "is", "awesome"};
String result4 = String.join(" ", words);
// 结果: "Java is awesome"

// Java 11+ repeat方法
String repeated = "Java ".repeat(3);  // "Java Java Java "

三、高级特性与最佳实践

3.1 字符串格式化

java

// 传统格式化
String formatted1 = String.format("姓名: %s, 年龄: %d, 分数: %.2f", 
                                 "张三", 25, 95.5);

// Java 15+ 文本块(多行字符串)
String json = """
    {
        "name": "张三",
        "age": 25,
        "skills": ["Java", "Spring", "MySQL"]
    }
    """;

3.2 性能优化:StringBuilder vs StringBuffer

java

// 不适合的场景 - 大量字符串拼接
String result = "";
for (int i = 0; i < 10000; i++) {
    result += i;  // 每次循环创建新String对象,性能差!
}

// 正确的做法 - 使用StringBuilder(非线程安全)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
    sb.append(i);
}
String result = sb.toString();

// StringBuffer(线程安全,性能稍差)
StringBuffer buffer = new StringBuffer();
buffer.append("线程安全").append("的字符串构建");

3.3 字符串池与intern方法

java

String s1 = "Java";              // 使用字符串池
String s2 = new String("Java");  // 创建新对象
String s3 = s2.intern();         // 放入并返回池中引用

System.out.println(s1 == s2);    // false
System.out.println(s1 == s3);    // true

3.4 正则表达式匹配

java

String email = "test@example.com";
String regex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$";

// 检查是否匹配
boolean isValid = email.matches(regex);

// 提取匹配内容
String text = "电话: 138-1234-5678, 备用: 139-8765-4321";
Pattern pattern = Pattern.compile("\\d{3}-\\d{4}-\\d{4}");
Matcher matcher = pattern.matcher(text);

while (matcher.find()) {
    System.out.println("找到号码: " + matcher.group());
}

四、实战应用示例

4.1 数据验证工具类

java

public class StringValidator {
    
    // 验证邮箱格式
    public static boolean isValidEmail(String email) {
        if (email == null || email.isBlank()) return false;
        String regex = "^[\\w.-]+@[\\w.-]+\\.\\w{2,}$";
        return email.matches(regex);
    }
    
    // 验证手机号
    public static boolean isValidPhone(String phone) {
        if (phone == null) return false;
        return phone.matches("1[3-9]\\d{9}");
    }
    
    // 隐藏敏感信息
    public static String maskSensitiveInfo(String input) {
        if (input == null || input.length() < 4) return input;
        return input.substring(0, 3) + "****" + 
               input.substring(input.length() - 4);
    }
}

4.2 字符串处理工具

java

public class StringProcessor {
    
    // 统计单词出现次数
    public static Map<String, Integer> wordFrequency(String text) {
        Map<String, Integer> frequency = new HashMap<>();
        if (text == null || text.isBlank()) return frequency;
        
        String[] words = text.toLowerCase()
                            .replaceAll("[^a-z\\s]", "")
                            .split("\\s+");
        
        for (String word : words) {
            frequency.put(word, frequency.getOrDefault(word, 0) + 1);
        }
        return frequency;
    }
    
    // 判断是否为回文
    public static boolean isPalindrome(String str) {
        if (str == null) return false;
        String cleaned = str.toLowerCase().replaceAll("[^a-z0-9]", "");
        return new StringBuilder(cleaned)
                .reverse()
                .toString()
                .equals(cleaned);
    }
}

五、常见陷阱与注意事项

  1. 不要用==比较字符串内容

    java

    String s1 = "hello";
    String s2 = new String("hello");
    System.out.println(s1 == s2);  // false!
    System.out.println(s1.equals(s2));  // true
  2. 注意字符串拼接的性能

    java

    // 错误示例 - 在循环中使用+
    String result = "";
    for (int i = 0; i < 10000; i++) {
        result += "data";  // 性能极差!
    }
    
    // 正确示例 - 使用StringBuilder
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 10000; i++) {
        sb.append("data");
    }
  3. 注意编码问题

    java

    // 指定字符编码
    String str = new String(bytes, StandardCharsets.UTF_8);
    byte[] bytes = str.getBytes(StandardCharsets.UTF_8);

六、总结

Java的String API虽然基础,但功能强大且实用。掌握这些API不仅能提高编码效率,还能写出更优雅、更高效的代码。记住:

  • 理解不可变性:这是String设计的核心

  • 选择合适的方法:根据场景选择最合适的API

  • 注意性能:特别是在处理大量字符串时

  • 善用工具类:Apache Commons Lang、Guava等库提供了更多实用功能


本篇博客涵盖了Java String API的核心内容,适用于Java 8及以上版本。实际开发中,请根据具体版本选择可用的API。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐