杰瑞科技汇

java string 动态数组

在 Java 中,并没有一个叫做 StringDynamicArray 的原生类,当我们谈论“字符串的动态数组”时,通常指的是以下两种情况:

java string 动态数组-图1
(图片来源网络,侵删)
  1. 可以动态增长的 String 数组:使用 Java 集合框架中的 ArrayList<String>
  2. String 本身的内部字符数组String 对象使用一个 char 数组来存储字符,这个数组在创建时大小固定,但 Java 提供了一些机制(如 StringBuilder)来高效地“动态”地构建字符串。

下面我们分别详细讲解这两种情况。


使用 ArrayList<String> 实现动态字符串数组

这是最常见、最推荐的方式,Java 的集合框架提供了 ArrayList 类,它内部使用一个数组来存储元素,但当数组空间不足时,它会自动创建一个更大的新数组,并将旧数组的元素复制过去,从而实现了“动态”增长。

ArrayList<String> 的核心特点:

  • 动态大小:可以随时添加或删除元素,无需关心底层数组的大小。
  • 类型安全:通过泛型 <String>,确保列表中只能存储 String 对象,避免了类型转换的麻烦和运行时错误。
  • 有序:元素的存储顺序就是它们被添加的顺序。
  • 允许重复元素:可以存储多个相同的 String

常用操作示例:

import java.util.ArrayList;
public class StringArrayListExample {
    public static void main(String[] args) {
        // 1. 创建一个 String 类型的 ArrayList
        ArrayList<String> names = new ArrayList<>();
        // 2. 添加元素 (add)
        names.add("Alice");
        names.add("Bob");
        names.add("Charlie");
        System.out.println("初始列表: " + names); // 输出: [Alice, Bob, Charlie]
        // 3. 在指定位置添加元素
        names.add(1, "David"); // 在索引 1 的位置插入 "David"
        System.out.println("插入后: " + names); // 输出: [Alice, David, Bob, Charlie]
        // 4. 获取元素 (get)
        String firstPerson = names.get(0);
        System.out.println("第一个名字是: " + firstPerson); // 输出: Alice
        // 5. 修改元素 (set)
        names.set(2, "Eve"); // 将索引 2 的元素 "Bob" 修改为 "Eve"
        System.out.println("修改后: " + names); // 输出: [Alice, David, Eve, Charlie]
        // 6. 删除元素 (remove)
        names.remove("David"); // 删除值为 "David" 的元素
        // names.remove(0);     // 也可以按索引删除,例如删除索引为 0 的元素
        System.out.println("删除后: " + names); // 输出: [Alice, Eve, Charlie]
        // 7. 获取列表大小 (size)
        System.out.println("列表大小: " + names.size()); // 输出: 3
        // 8. 遍历列表
        System.out.println("遍历列表:");
        for (String name : names) {
            System.out.println(name);
        }
        // 9. 检查元素是否存在 (contains)
        System.out.println("列表中是否包含 'Alice'? " + names.contains("Alice")); // 输出: true
        // 10. 转换为固定大小的数组 (toArray)
        String[] namesArray = names.toArray(new String[0]);
        System.out.println("转换为数组后的第一个元素: " + namesArray[0]); // 输出: Alice
    }
}

String 内部的字符数组与 StringBuilder

String 对象在 Java 中是不可变的(immutable),这意味着一旦一个 String 对象被创建,它的内容就不能被改变,任何看起来像是修改字符串的操作(如 concat, replace),实际上都是创建了一个新的 String 对象,而原来的对象保持不变。

如果需要进行大量的字符串拼接或修改操作,频繁地创建新 String 对象会非常低效,这时,我们就需要使用“可变”的字符序列,也就是 StringBuilderStringBuffer

java string 动态数组-图2
(图片来源网络,侵删)

StringBuilder 的核心特点:

  • 可变性StringBuilder 对象内部的字符数组可以被修改,而不会创建新的对象。
  • 高性能:对于字符串的拼接、插入、删除等操作,StringBuilder 的性能远高于直接使用 String 的 号或 concat 方法。
  • 非线程安全:它的方法不是同步的,因此在单线程环境中使用效率更高,如果需要在多线程环境中使用,应使用 StringBuffer(它是线程安全的,但性能稍差)。

StringBuilder 的工作原理(动态数组思想):

StringBuilder 内部维护一个可变的 char[] 数组,当你调用 append() 方法时:

  1. 如果当前数组还有剩余空间,就直接将新字符添加到末尾。
  2. 如果空间不足,它会自动创建一个更大的新数组(通常是容量的 2 倍 + 2),将旧数组的内容复制到新数组,然后添加新字符。

这个过程与 ArrayList 的扩容机制非常相似,都是动态数组思想的体现。

StringBuilder 操作示例:

public class StringBuilderExample {
    public static void main(String[] args) {
        // 1. 创建一个 StringBuilder 对象
        StringBuilder sb = new StringBuilder();
        // 2. 添加字符/字符串 (append)
        sb.append("Hello");
        sb.append(" ");
        sb.append("World");
        System.out.println("拼接后: " + sb.toString()); // 输出: Hello World
        // 3. 插入字符/字符串 (insert)
        sb.insert(5, ","); // 在索引 5 的位置插入 ","
        System.out.println("插入后: " + sb.toString()); // 输出: Hello, World
        // 4. 删除字符 (delete)
        sb.delete(5, 7); // 删除从索引 5 (包含) 到 7 (不包含) 的字符,即删除 ", "
        System.out.println("删除后: " + sb.toString()); // 输出: HelloWorld
        // 5. 反转字符串 (reverse)
        sb.reverse();
        System.out.println("反转后: " + sb.toString()); // 输出: dlroWolleH
        // 6. 获取最终字符串 (toString)
        // 当操作完成后,调用 toString() 方法将其转换为一个不可变的 String 对象
        finalResult = sb.toString();
        System.out.println("最终结果: " + finalResult);
    }
}

总结与对比

特性 ArrayList<String> String / StringBuilder
用途 存储多个字符串的集合,像一个动态的字符串列表。 存储和操作单个字符串序列。
核心思想 一个可以动态增长的 String 对象的容器。 一个内部使用动态数组的、可变的字符序列。
可变性 ArrayList 本身是可变的(可以增删改元素),但它存储的 String 对象是不可变的。 String 不可变StringBuilder 可变
性能 增删元素有开销(特别是中间位置),但比频繁创建 String 高效得多。 StringBuilder 的拼接操作非常高效,避免了创建大量临时 String 对象。
如何选择 - 当你需要一个列表来存放一组字符串时(学生名单、单词列表)。
- 当你需要对字符串集合进行排序、搜索等操作时。
- 当你需要在一个循环中频繁地拼接、修改一个字符串时(构建 SQL 语句、JSON 数据)。
- 当你需要从不同来源高效地组合一个最终字符串时。

  • 想管理一堆字符串,用 ArrayList<String>
  • 想高效地构建或修改一个字符串,用 StringBuilder
java string 动态数组-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇