2017-10-04 75 views
-3

所以我有這段代碼:操縱一個StringBuilder在java的一個StringBuilder陣列

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 []的行爲不同,我想了解原因。

+0

你什麼意思「fill()的行爲與StringBuilder []」的行爲不同,我相信它不會。 – daniu

+2

你能說明'StringBuilder'有什麼不同嗎?你能提供一個帶有*不同類別的樣本嗎?這會產生不同的結果嗎? –

回答

1

我敢肯定的說:「fill()只有StringBuidler[]表現不同」,是因爲你只與其他不變對象嘗試的原因,而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的,所包含的條目。

+0

哦,我不知道'StringBuilder'是可變的,'String'(我試過的那些)不是。對不起,浪費你的時間。從現在起會更加周到。 –

1

APIArrays.fill ...

分配指定的Object參考指定的對象的陣列中的每個元素。

所以,是的,它是相同的,不幸的是你需要某種形式的迭代到不同StringBuilder分配給所有元素。

5

您看到的行爲是預期的。

引用the javadoc of Arrays.fill()

分配指定的對象引用到指定的對象的陣列中的每個元素。

重點煤礦。

這裏指的是在原型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);