在 java 中操作 StringBuilder 数组中的 StringBuilder

manipulate a StringBuilder in a StringBuilder array in java

所以我有这段代码:

StringBuilder[] a = new StringBuilder[5];
        Arrays.fill(a, new StringBuilder("asdfg"));
        a[0].deleteCharAt(0);
        for (StringBuilder s : a) {
            System.out.println(s);
        }

和输出

sdfg
sdfg
sdfg
sdfg
sdfg

似乎数组中的所有元素都是对同一个 StringBuilder 对象的引用,我猜是因为 Arrays.fill()。为什么会发生这种情况,我该如何解决? p.s:我不想使用循环,因为 fill() 仅在 StringBuilder[] 中表现不同,我想了解原因。

来自 APIArrays.fill...

Assigns the specified Object reference to each element of the specified array of Objects.

所以是的,它是相同的引用,不幸的是您需要某种形式的迭代来为所有元素分配不同的StringBuilder

您看到的行为是正常的。

引用 the javadoc of Arrays.fill():

Assigns the specified Object reference to each element of the specified array of Objects.

强调我的。

这里引用的是原型中的val(回想一下:public static void fill(Object[] a, Object val),也就是你的new StringBuilder("asdfg").

如果要用不同个元素填充数组的每个元素,则需要循环遍历数组索引并每次填充一个新对象。例如(使用 Java 8):

IntStream.range(O, a.length).foreach(index -> a[index] = new StringBuilder("asdfg"));

附带说明一下,您可以直接使用 IntStream 来构建数组,但我不确定代码是否真的清晰易读。 流API滥用警告!

final StringBuilder[] a = IntStream.range(0, 5)
    .mapToObj(ignored -> new StringBuilder("asdfg"))
    .toArray(StringBuilder[]::new);

我敢肯定说“fill() 仅在 StringBuidler[] 下表现不同”的原因是因为您只尝试过其他 immutable 对象,而 StringBuilder 不是。尝试

List<String> list[] = new List[5];
Arrays.fill(list, new ArrayList<String>());
list[0].add("hello");
for (List l : list) {
    System.out.println(l);
}

不可变意味着在实例上调用方法不会改变它的状态(就像在 StringBuilder 的情况下,累积的 String,或者在 List 的情况下,包含的条目。