我只能用String来做到这一点,例如:
String str="";
for(int i=0;i<100;i++){
str=i+str;
}
有没有办法用StringBuilder做到这一点?谢谢。
Answers:
StringBuilder sb = new StringBuilder();
for(int i=0;i<100;i++){
sb.insert(0, Integer.toString(i));
}
警告: 它违背了的目的StringBuilder
,但确实满足您的要求。
更好的技术(尽管仍然不理想):
StringBuilder
。StringBuilder
过程。这将打开一个O(ñ ²)溶液到O(Ñ)。
也许我缺少了一些东西,但是您想用一个看起来像这样的String结束,对"999897969594...543210"
吗?
StringBuilder sb = new StringBuilder();
for(int i=99;i>=0;i--){
sb.append(String.valueOf(i));
}
作为一种替代解决方案,您可以使用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();
ArrayDeque
应该代替Stack
。“ {@link Deque}接口及其实现提供了一套更完整和一致的LIFO堆栈操作,应优先使用此类。”
该线程已经很老了,但是您也可以考虑将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));
}
}
}
当我偶然发现这篇文章时,我有一个类似的要求。我想要一种快速的方法来构建一个可以从两端都扩展的字符串。在前面和后面任意添加新字母。我知道这是一篇过时的文章,但是它启发了我尝试一些创建字符串的方法,并且我认为我会分享自己的发现。我还在其中使用了一些Java 8构造,这些构造在情况4和5中可以优化速度。
https://gist.github.com/SidWagz/e41e836dec65ff24f78afdf8669e6420
上面的要点包含任何人都可以运行的详细代码。在这种情况下,我采取了几种方法来增加字符串;1)附加到StringBuilder,2)如@Mehrdad所示,插入到StringBuilder的前面,3)从StringBuilder的前面和结尾部分插入,4)使用列表从结尾追加,5)使用双端队列从前面追加。
// 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个字符的字符串(仍然很多),则前面的插入将通过在末尾追加来构建具有相同长度的String的同时构建一个String。我的意思是,时间惩罚的确确实存在并且是巨大的,但是只有当您必须构建非常大的字符串时。如我的示例所示,可以使用双端队列并在最后连接字符串。
实际上,情况2的性能比情况1快得多,我似乎并不了解。我假设StringBuilder中内部缓冲区的增长在前附加和后附加的情况下是相同的。我什至将最小堆设置为非常大的数量,以避免延迟堆增长(如果这样做会起作用)。也许有更好理解的人可以在下面发表评论。
Difference Between String, StringBuilder And StringBuffer Classes
String
String is immutable ( once created can not be changed )object. The object created as a
String is stored in the Constant String Pool.
Every immutable object in Java is thread-safe, which implies String is also thread-safe. String
can not be used by two threads simultaneously.
String once assigned can not be changed.
StringBuffer
StringBuffer is mutable means one can change the value of the object. The object created
through StringBuffer is stored in the heap. StringBuffer has the same methods as the
StringBuilder , but each method in StringBuffer is synchronized that is StringBuffer is thread
safe .
Due to this, it does not allow two threads to simultaneously access the same method. Each
method can be accessed by one thread at a time.
But being thread-safe has disadvantages too as the performance of the StringBuffer hits due
to thread-safe property. Thus StringBuilder is faster than the StringBuffer when calling the
same methods of each class.
String Buffer can be converted to the string by using
toString() method.
StringBuffer demo1 = new StringBuffer("Hello") ;
// The above object stored in heap and its value can be changed.
/
// Above statement is right as it modifies the value which is allowed in the StringBuffer
StringBuilder
StringBuilder is the same as the StringBuffer, that is it stores the object in heap and it can also
be modified. The main difference between the StringBuffer and StringBuilder is
that StringBuilder is also not thread-safe.
StringBuilder is fast as it is not thread-safe.
/
// The above object is stored in the heap and its value can be modified
/
// Above statement is right as it modifies the value which is allowed in the StringBuilder
怎么样:
StringBuilder builder = new StringBuilder();
for(int i=99;i>=0;i--){
builder.append(Integer.toString(i));
}
builder.toString();
要么
StringBuilder builder = new StringBuilder();
for(int i=0;i<100;i++){
builder.insert(0, Integer.toString(i));
}
builder.toString();
但是,与此同时,您正在执行操作O(N ^ 2)而不是O(N)。
来自Java文档的代码段:
将Object参数的字符串表示形式插入此字符序列。总体效果与方法将第二个参数转换为
String.valueOf(Object)
字符串一样,然后将该字符串的字符以指定的偏移量插入到此字符序列中。
AbstractStringBuilder
所有内容都移到插入索引之外,以便为插入的内容找到空间。但是,这只是实现细节,而不是原理之一。