字符串

面向对象程序设计(Java)

掌握字符串处理,为后续复杂文本处理打下基础

String 类

字符串String 是Java中一个非常特殊的类,用于表示一系列字符。字符串是不可变的,一旦创建,其内容无法修改。

public static void main(String[] args) {
    // 1. 直接使用双引号创建(推荐)
    String str1 = "Hello World";

    // 2. 使用构造方法创建
    String str2 = new String("Hello World");

    // "==" 比较的是引用地址
    System.out.println(str1 == str2); // false

    // .equals() 比较的是内容
    System.out.println(str1.equals(str2)); // true
}

为了优化性能,内容相同的字符串字面量在内存中通常只有一个实例。
因此,比较字符串内容时,务必使用 .equals() 方法。

常用的String方法

String 类提供了丰富的方法来操作字符串。

public static void main(String[] args) {
    String str = "Hello, World!";

    // 获取长度
    System.out.println("长度: " + str.length());

    // 截取子串
    String sub = str.substring(7, 12); // "World"
    System.out.println("子串: " + sub);

    // 分割字符串
    String[] parts = str.split(", "); // ["Hello", "World!"]
    for (String part : parts) {
        System.out.println("分割部分: " + part);
    }

    // 转换为字符数组
    char[] chars = str.toCharArray();
    System.out.println("第一个字符: " + chars[0]);
}

由于字符串不可变,所有修改字符串内容的方法(如 substring, split)都会返回一个新的 String 对象。

提问:如何快速判断一个字符串是否是回文字串?

格式化输出

当你要把数据“排版”成可读文本时,格式化比字符串拼接更清晰、更稳定。

拼接(能用但可读性一般)

double pi = 3.1415926;
System.out.println("pi=" + pi + ", score=" + 95);

格式化(可控精度与对齐)

double pi = 3.1415926;
System.out.printf("pi=%.2f, score=%d%n", pi, 95);

String s = String.format("pi=%.4f", pi);
System.out.println(s);

常用格式符

  • %d 整数,%,d 带千分位
  • %f 小数,%.2f 保留两位
  • %s 字符串,%.10s 截断到 10 个字符
  • %n 换行(跨平台)
import java.util.Formatter;

public class FormatterDemo {
    public static void main(String[] args) {
        try (Formatter fm = new Formatter()) {
            fm.format("price=%.2f, name=%.5s%n", 123.4567, "Learning");
            System.out.print(fm);
        }
    }
}

StringTokenizer

StringTokenizer 是早期 Java 的分词工具:轻量、基于分隔符,但功能相对简单。

import java.util.StringTokenizer;

public class TokenizerDemo {
    public static void main(String[] args) {
        String s = "This  is  geek";
        StringTokenizer st = new StringTokenizer(s, " ");
        while (st.hasMoreTokens()) {
            System.out.println(st.nextToken());
        }
    }
}

什么时候用?什么时候不用?

  • 只需要“按单个分隔符快速切割”,且不想引入正则:可以用
  • 需要正则、复杂分隔、保留空串:用 String.split 或 Pattern
  • 需要从输入流按 token 读取:用 Scanner(但注意性能与分隔规则)

新代码更常见的选择是 split 或 Pattern;StringTokenizer 主要用于读旧代码与理解历史。

StringBuilder与StringBuffer

当需要频繁拼接或修改字符串时,使用 String 会产生大量临时对象,效率较低。此时应使用 StringBuilder 或 StringBuffer。

🔧 基本使用方法

public static void main(String[] args) {
    // StringBuilder示例
    StringBuilder builder = new StringBuilder();
    builder.append("你好");
    builder.append(",世界!");
    builder.append(2024);
    
    String result = builder.toString();
    System.out.println(result); // "你好,世界!2024"

    // StringBuffer示例(用法完全相同)
    StringBuffer buffer = new StringBuffer();
    buffer.append("Hello");
    buffer.append(", ");
    buffer.append("Java!");
    
    System.out.println(buffer.toString()); // "Hello, Java!"
}

⚖️ StringBuilder vs StringBuffer 对比

特性 StringBuilder StringBuffer
线程安全 ❌ 非线程安全 ✅ 线程安全(synchronized)
性能 🚀 更快 🐌 稍慢(同步开销)
引入版本 Java 5+ Java 1.0+
使用场景 单线程环境(推荐) 多线程环境

💡 选择建议

  • 优先选择 StringBuilder:在99%的情况下,单线程操作更常见
  • 多线程场景使用 StringBuffer:当多个线程同时操作同一个字符串缓冲区时
  • 性能对比:StringBuilder > StringBuffer > String拼接

在循环或大量拼接场景下,StringBuilder 是构建字符串的最佳选择;多线程环境下使用 StringBuffer。

正则表达式

正则表达式 (Regular Expression)是一种描述字符串匹配模式的强大工具,可用于验证、查找、替换字符串。

例如,验证一个字符串是否由一个或多个 'o' 组成:

public static void main(String[] args) {
    String str1 = "oooo";
    String str2 = "o";
    String str3 = "oops";

    // "o+" 是一个正则表达式,+ 表示匹配前面的字符一次或多次
    System.out.println(str1.matches("o+")); // true
    System.out.println(str2.matches("o+")); // true
    System.out.println(str3.matches("o+")); // false
}

正则表达式语法复杂但功能强大,是处理文本的重要技能。

1 / X