ZetCode

Java CharSequence 接口

最后修改时间:2025 年 4 月 13 日

java.lang.CharSequence 接口表示字符值的可读序列,提供文本数据的一致且不可变的视图。它作为各种字符序列类型的抽象,允许统一访问其内容。此接口由多个类实现,包括 StringStringBuilderStringBuffer,每个类都提供不同的功能来处理和操作文本。

CharSequence 在 Java 1.4 中引入,旨在统一不同字符序列类型的操作。它提供了几种方法,例如

由于 CharSequence 是一个接口,它不提供具体的实现,而是定义一个实现类必须遵循的约定。例如,String 类表示不可变的字符序列,而 StringBuilderStringBuffer 允许具有不同线程行为的可变字符串操作。

许多 Java API 接受 CharSequence 作为参数,从而在使用不同类型的字符序列时实现灵活性。这种抽象使得处理文本更容易,而无需局限于特定的底层实现。

CharSequence 接口方法

CharSequence 接口定义了几个用于检查字符的方法。这些方法必须由所有实现该接口的类来实现。主要方法包括 lengthcharAtsubSequencetoString

CharSequence 的基本用法

此示例演示了 CharSequence 与不同实现的基本用法。 我们展示了如何将接口方法与 StringStringBuilderStringBuffer 一起使用。

Main.java
void main() {

    // Different CharSequence implementations
    CharSequence str = "Hello World";
    CharSequence sb = new StringBuilder("Java Programming");
    CharSequence sbf = new StringBuffer("CharSequence Demo");
    
    // Common operations
    System.out.println("String length: " + str.length());
    System.out.println("5th char in StringBuilder: " + sb.charAt(4));
    System.out.println("Subsequence of StringBuffer: " + 
                        sbf.subSequence(0, 11));
    
    // toString() usage
    String s = str.toString();
    System.out.println("Converted to String: " + s);
}

此示例显示了 CharSequence 如何为不同的字符序列类型提供一个公共接口。 无论底层实现如何,我们都可以调用相同的方法。 toString 方法在需要时将任何 CharSequence 转换为 String

CharSequence 与 String

字符串是最常见的 CharSequence 实现。 此示例显示了通过 CharSequence 接口的特定 String 操作。

Main.java
void processSequence(CharSequence seq) {

    System.out.println("Processing sequence: " + seq);
    System.out.println("Length: " + seq.length());
    System.out.println("First char: " + seq.charAt(0));
    System.out.println("Last char: " + seq.charAt(seq.length() - 1));
}

void main() {

    String text = "Programming in Java";
    processSequence(text);
    processSequence(text.subSequence(0, 11));
}

在这里,我们演示了 String 如何作为 CharSequence 工作。 processSequence 方法接受任何 CharSequence,允许它与完整的 String 及其子序列一起使用。 这显示了面向接口编程的灵活性。

CharSequence 与 StringBuilder

StringBuilder 是一个可变的 CharSequence 实现。 此示例显示了如何在保持可变性的同时,通过 CharSequence 接口使用 StringBuilder

Main.java
void main() {

    StringBuilder sb = new StringBuilder("Initial Value");
    CharSequence cs = sb;
    
    System.out.println("Original: " + cs);
    System.out.println("Length: " + cs.length());
    System.out.println("Char at 3: " + cs.charAt(3));
    
    // Mutate the underlying StringBuilder
    sb.append(" Appended");
    System.out.println("After mutation: " + cs);
    
    // Create subsequence
    CharSequence sub = cs.subSequence(8, 13);
    System.out.println("Subsequence: " + sub);
}

此示例演示了虽然 CharSequence 本身是只读的,但底层 StringBuilder 仍然是可变的。 通过 CharSequence 引用,可以观察到对 StringBuilder 的更改。 子序列操作会创建原始序列的部分的新 CharSequence 视图。

正则表达式中的 CharSequence

Java 的正则表达式 API 广泛使用 CharSequence。 此示例显示了使用不同 CharSequence 实现的模式匹配。

Main.java
void main() {

    Pattern pattern = Pattern.compile("\\d{3}-\\d{2}-\\d{4}");
    
    CharSequence[] inputs = {
        "123-45-6789", // String
        new StringBuilder("987-65-4321"),
        new StringBuffer("Invalid-12-3456"),
        "Another invalid 12-34-5678"
    };
    
    for (CharSequence input : inputs) {
        Matcher matcher = pattern.matcher(input);
        System.out.println(input + ": " + 
                            (matcher.matches() ? "Valid" : "Invalid"));
    }
}

此示例演示了 Java 的 regex API 如何接受任何 CharSequence。 我们针对社会安全号码模式测试不同的实现。 PatternMatcher 类适用于所有 CharSequence 类型,显示了接口在 API 设计中的实用性。

自定义 CharSequence 实现

此示例显示了如何创建自定义 CharSequence 实现。 我们将构建一个简单的序列,该序列反转另一个 CharSequence

Main.java
public class ReverseCharSequence implements CharSequence {

    private final CharSequence original;
    
    public ReverseCharSequence(CharSequence original) {
        this.original = original;
    }
    
    @Override
    public int length() {
        return original.length();
    }
    
    @Override
    public char charAt(int index) {
        return original.charAt(original.length() - 1 - index);
    }
    
    @Override
    public CharSequence subSequence(int start, int end) {
        return new ReverseCharSequence(
            original.subSequence(original.length() - end, 
                               original.length() - start));
    }
    
    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder(length());
        for (int i = 0; i < length(); i++) {
            sb.append(charAt(i));
        }
        return sb.toString();
    }
}

void main() {

    CharSequence original = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    CharSequence reversed = new ReverseCharSequence(original);
    
    System.out.println("Original: " + original);
    System.out.println("Reversed: " + reversed);
    System.out.println("5th char: " + reversed.charAt(4));
    System.out.println("Subseq(5-10): " + 
                        reversed.subSequence(5, 10));
}

此示例演示了创建自定义 CharSequence,该序列反转另一个序列。 ReverseCharSequence 类实现所有必需的方法,提供原始序列的反向顺序视图。 这显示了如何使用 CharSequence 来创建专门的序列视图。

CharSequence 性能注意事项

此示例比较了不同 CharSequence 实现的常见操作的性能特征。

Main.java
public static void measurePerformance(CharSequence seq, String type) {

    final int ITERATIONS = 1000000;
    
    // Measure charAt performance
    long start = System.nanoTime();
    for (int i = 0; i < ITERATIONS; i++) {
        seq.charAt(i % seq.length());
    }
    long duration = System.nanoTime() - start;
    System.out.printf("%s charAt: %d ns%n", type, duration/ITERATIONS);
    
    // Measure subSequence performance
    start = System.nanoTime();
    for (int i = 0; i < ITERATIONS; i++) {
        seq.subSequence(0, seq.length() / 2);
    }
    duration = System.nanoTime() - start;
    System.out.printf("%s subSequence: %d ns%n", type, duration/ITERATIONS);
}

void main() {

    CharSequence str = "PerformanceTestString";
    CharSequence sb = new StringBuilder("PerformanceTestString");
    CharSequence sbf = new StringBuffer("PerformanceTestString");
    
    measurePerformance(str, "String");
    measurePerformance(sb, "StringBuilder");
    measurePerformance(sbf, "StringBuffer");
}

此示例测量了跨不同实现的 CharSequence 基本操作的性能。 String 通常提供最快的读取操作,而 StringBuilder 和 StringBuffer 可能具有不同的性能特征。 结果可能因 JVM 实现和版本而异。

来源

Java CharSequence 接口文档

在本文中,我们通过实际示例介绍了 Java CharSequence 接口。 理解 CharSequence 对于编写灵活的 API 非常有价值,这些 API 可以有效地与不同字符序列类型一起使用。

作者

我的名字是 Jan Bodnar,我是一位敬业的程序员,在该领域拥有多年的经验。 我于 2007 年开始撰写编程文章,此后撰写了 1,400 多篇文章和八本电子书。 凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程