これはStringでしかできませんでした。例:
String str="";
for(int i=0;i<100;i++){
str=i+str;
}
StringBuilderでこれを実現する方法はありますか?ありがとう。
これはStringでしかできませんでした。例:
String str="";
for(int i=0;i<100;i++){
str=i+str;
}
StringBuilderでこれを実現する方法はありますか?ありがとう。
回答:
StringBuilder sb = new StringBuilder();
for(int i=0;i<100;i++){
sb.insert(0, Integer.toString(i));
}
警告: それはの目的を無効StringBuilder
にしますが、あなたが求めたことを実行します。
より良いテクニック(まだ理想的ではありませんが):
StringBuilder
。StringBuilder
ます。これはO(オンになりますN ²)Oへの溶液(N)を。
何かが足りないかもしれませんが、次のような文字列を作成したいのですが"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
ます。「より完全で一貫性のあるLIFOスタック操作のセットは、{@ link Deque}インターフェイスとその実装によって提供されます。これは、このクラスよりも優先して使用する必要があります。」
このスレッドはかなり古いですが、StringBuilderを渡してfillする再帰的なソリューションについて考えることもできます。これにより、逆処理などを防ぐことができます。再帰を使用して反復を設計し、終了条件を慎重に決定する必要があります。
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)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の実装は、内部バッファーの拡張方法を内部的に決定します。これは、フロントアペンディングの場合にすべてのバッファーを左から右に移動する以外に、速度を制限します。@Mehrdadに示されているように、StringBuilderの前面に直接挿入するのにかかる時間は非常に長い値になりますが、90k文字未満の長さの文字列のみが必要な場合(これはまだ多いです)、前面の挿入は最後に追加して同じ長さの文字列を作成するのと同じ時間に文字列を作成します。私が言っているのは、時間のペナルティは確かにキックして巨大であるということですが、それはあなたが本当に巨大なストリングを構築しなければならないときだけです。私の例に示すように、両端キューを使用して、最後に文字列を結合することができます。
実際、ケース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)ではなくO(N ^ 2)の操作を行うことになります。
Javaドキュメントからのスニペット:
Object引数の文字列表現をこの文字シーケンスに挿入します。全体的な効果は、2番目の引数がメソッドによって文字列に変換され、
String.valueOf(Object)
その文字列の文字が指定されたオフセットでこの文字シーケンスに挿入された場合とまったく同じ です。
AbstractStringBuilder
挿入されたコンテンツのスペースを見つけるために、すべてのコンテンツを挿入インデックスを超えて移動するためです。ただし、これは実装の詳細であり、原則の1つではありません。