2011-05-09 75 views

回答

116
StringBuilder sb = new StringBuilder(); 
for(int i=0;i<100;i++){ 
    sb.insert(0, Integer.toString(i)); 
} 

警告:它違背了StringBuilder的目的,但它確實你的要求。


更好的技術(儘管仍然不理想):

  1. 反向要插入每個字符串。
  2. 附加每個字符串到StringBuilder
  3. 反轉整個StringBuilder完成後。

這會變成一個O(ñ²)溶液到O(Ñ)。

+0

...因爲它使'AbstractStringBuilder'將所有內容移過插入索引,以便爲插入索引找到空間。但是,這是一個實現細節,不是一個原則。 – entonio 2011-05-09 00:18:02

+1

@entonio:確實,但它是一個非常關鍵的細節。 :) – Mehrdad 2011-05-09 00:19:00

+1

我看,它看起來像我不應該使用StringBuilder然後,非常感謝 – user685275 2011-05-09 00:25:48

18

可以使用strbuilder.insert(0,i);

7

也許我失去了一些東西,但你想用一個字符串看起來像這樣,"999897969594...",正確拉閘?

StringBuilder sb = new StringBuilder(); 
for(int i=99;i>=0;i--){ 
    sb.append(String.valueOf(i)); 
} 
+0

奇怪的這篇文章沒有得到太多的投票,同時通過巧妙的循環提供解決方案, – 2014-11-17 09:56:35

+1

@ nom-mon-ir他只是顛倒了字符串。它不回答如何追加在左邊。 – 2015-10-14 19:59:52

+0

達到預期的效果。 – Speck 2015-10-15 14:50:53

3

這個線程很舊,但你也可以考慮通過StringBuilder來填充的遞歸解決方案。這可以防止任何反向處理等。只需要用遞歸設計迭代並仔細決定退出條件。

public class Test { 

    public static void main(String[] args) { 
     StringBuilder sb = new StringBuilder(); 
     doRecursive(sb, 100, 0); 
     System.out.println(sb.toString()); 
    } 

    public static void doRecursive(StringBuilder sb, int limit, int index) { 
     if (index < limit) { 
      doRecursive(sb, limit, index + 1); 
      sb.append(Integer.toString(index)); 
     } 
    } 
} 
6

正如你可以使用LIFO結構(如棧)來存儲所有的字符串,當你完成只是把他們都攆出去,並把它們放到StringBuilder的替代解決方案。它自然會顛倒放置在其中的項目(字符串)的順序。

Stack<String> textStack = new Stack<String>(); 
// push the strings to the stack 
while(!isReadingTextDone()) { 
    String text = readText(); 
    textStack.push(text); 
} 
// pop the strings and add to the text builder 
String builder = new StringBuilder(); 
while (!textStack.empty()) { 
     builder.append(textStack.pop()); 
} 
// get the final string 
String finalText = builder.toString(); 
+3

'ArrayDeque'應該用來代替'Stack'。 「{@link Deque}接口及其實現應提供更完整和一致的LIFO堆棧操作集,這些操作應優先於此類使用。」 – 2016-01-22 22:51:52

0

當我偶然發現這篇文章時,我有類似的要求。我想要一個快速的方法來構建一個可以從兩邊增長的字符串,即。在前面添加新字母以及隨意添加。我知道這是一箇舊帖子,但它激勵我嘗試幾種創建字符串的方式,我想我會分享我的發現。我也是用這個一些Java 8層結構,這可能會在案件4優化了速度和5

https://gist.github.com/SidWagz/e41e836dec65ff24f78afdf8669e6420

上面的要點有詳細的代碼,任何人都可以運行。 我在這方面採取了幾種方式增長字符串; 1)附加到StringBuilder,2)插入到StringBuilder的前面,如@Mehrdad所示,3)從StringBuilder的前面和末尾部分插入,4)使用列表從末尾追加,5)使用Deque從前面追加。

// Case 2  
StringBuilder build3 = new StringBuilder(); 
IntStream.range(0, MAX_STR) 
        .sequential() 
        .forEach(i -> { 
         if (i%2 == 0) build3.append(Integer.toString(i)); else build3.insert(0, Integer.toString(i)); 
        }); 
String build3Out = build3.toString(); 


//Case 5 
Deque<String> deque = new ArrayDeque<>(); 
IntStream.range(0, MAX_STR) 
       .sequential() 
       .forEach(i -> { 
        if (i%2 == 0) deque.addLast(Integer.toString(i)); else deque.addFirst(Integer.toString(i)); 
       }); 

String dequeOut = deque.stream().collect(Collectors.joining("")); 

我會專注於前面追加唯一的情況下,即。情況2和情況5. StringBuilder的實現在內部決定內部緩衝區的增長方式,除了在前追加的情況下從左向右移動所有緩衝區限制速度。雖然直接插入到StringBuilder前面的時間增長到非常高的值,如@Mehrdad所示,如果需要只有長度小於90k字符的字符串(這仍然很多),則前插入將會在建立一個字符串的同時,通過在最後添加一個長度相同的字符串來構建一個字符串。我說的是,時間的罰款確實是巨大的,但只有當你必須建立真正的巨大的字符串。可以使用deque並在末尾加入字符串,如我的示例中所示。但是,StringBuilder讀取和編寫代碼更直觀,對於較小的字符串,懲罰並不重要。

事實上,案例2的性能比情況1快得多,我似乎並不明白。我假設StringBuilder中的內部緩衝區的增長在前追加和後追加的情況下是相同的。我甚至將最小堆設置爲非常大的數量,以避免堆增長的延遲,如果這會起到作用的話。也許有更好理解的人可以在下面發表評論。

相關問題