Bunu yalnızca String ile yapabilirdim, örneğin:
String str="";
for(int i=0;i<100;i++){
str=i+str;
}
Bunu StringBuilder ile başarmanın bir yolu var mı? Teşekkürler.
Bunu yalnızca String ile yapabilirdim, örneğin:
String str="";
for(int i=0;i<100;i++){
str=i+str;
}
Bunu StringBuilder ile başarmanın bir yolu var mı? Teşekkürler.
Yanıtlar:
StringBuilder sb = new StringBuilder();
for(int i=0;i<100;i++){
sb.insert(0, Integer.toString(i));
}
Uyarı: Amacını bozarStringBuilder
, ancak istediğinizi yapar.
Daha iyi teknik (yine de ideal olmasa da):
StringBuilder
.StringBuilder
.Bu bir O ( n ²) çözümünü O ( n ) 'ye çevirecektir .
kullanabilirsiniz strbuilder.insert(0,i);
Belki bir şeyi kaçırıyorum ama bunun gibi görünen bir String ile bitmek istiyorsun, değil mi "999897969594...543210"
?
StringBuilder sb = new StringBuilder();
for(int i=99;i>=0;i--){
sb.append(String.valueOf(i));
}
Alternatif bir çözüm olarak, tüm dizeleri depolamak için bir LIFO yapısı (bir yığın gibi) kullanabilirsiniz ve işiniz bittiğinde hepsini çıkarın ve StringBuilder'a koyun. İçine yerleştirilen öğelerin (dizelerin) sırasını doğal olarak tersine çevirir.
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
yerine kullanılmalıdır Stack
. "Daha eksiksiz ve tutarlı bir LIFO yığın işlemleri seti, {@link Deque} arayüzü ve bu sınıfa tercih edilerek kullanılması gereken uygulamaları tarafından sağlanır."
Bu iş parçacığı oldukça eskidir, ancak StringBuilder'ı doldurmak için geçiren özyinelemeli bir çözüm de düşünebilirsiniz. Bu, herhangi bir ters işlemeyi önlemeye izin verir. Sadece yinelemenizi bir özyineleme ile tasarlamanız ve bir çıkış durumuna dikkatlice karar vermeniz gerekir.
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));
}
}
}
Bu yazıya tökezlediğimde benzer bir şartım vardı. Her iki taraftan da büyüyebilen bir String oluşturmanın hızlı bir yolunu istedim, yani. keyfi olarak öne ve arkaya yeni harfler ekleyin. Bunun eski bir gönderi olduğunu biliyorum, ancak dizeler oluşturmanın birkaç yolunu denemem için bana ilham verdi ve bulgularımı paylaşacağımı düşündüm. Ayrıca, 4 ve 5 numaralı durumlarda hızı optimize edebilecek bazı Java 8 yapıları kullanıyorum.
https://gist.github.com/SidWagz/e41e836dec65ff24f78afdf8669e6420
Yukarıdaki Özet, herkesin çalıştırabileceği ayrıntılı bir koda sahiptir. Bunda ipleri büyütmenin birkaç yolunu seçtim; 1) StringBuilder'a ekleyin, 2) @Mehrdad tarafından gösterildiği gibi StringBuilder'ın önüne ekleyin, 3) StringBuilder'ın önünden ve sonundan kısmen ekleyin, 4) Sondan eklemek için bir liste kullanmak, 5) ön taraftan ekleyin.
// 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(""));
Sadece öndeki ek durumlara odaklanacağım yani. durum 2 ve durum 5. StringBuilder uygulaması dahili olarak dahili tamponun nasıl büyüdüğüne karar verir; bu, ön ekleme durumunda tüm tamponun soldan sağa taşınmasının yanı sıra hızı sınırlar. StringBuilder'ın doğrudan önüne eklerken geçen süre, @Mehrdad tarafından gösterildiği gibi gerçekten yüksek değerlere ulaşırken, ihtiyaç yalnızca 90k karakterden daha az uzunlukta dizelere sahip olmaksa (ki bu hala çok fazladır), ön ekleme Sonuna ekleyerek aynı uzunlukta bir String oluşturmak için gereken zamanda bir String oluşturun. Demek istediğim, zaman cezasının gerçekten tekme attığı ve çok büyük olduğu, ancak yalnızca gerçekten çok büyük dizeler oluşturmanız gerektiğinde. Benim örneğimde gösterildiği gibi bir deque kullanabilir ve sondaki dizeleri birleştirebilir.
Aslında durum 2'nin performansı, durum 1'den çok daha hızlı, ki bunu anlamıyorum. StringBuilder'daki dahili tampon için büyümenin ön ekleme ve arka ekleme durumunda aynı olacağını varsayıyorum. Hatta bir rol oynamış olsaydı, yığın büyümesinde gecikmeyi önlemek için minimum yığını çok büyük bir miktara ayarladım. Belki daha iyi anlayan biri aşağıya yorum yapabilir.
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
Ofset ile ekleme yöntemini kullanabilirsiniz. ofset olarak '0' olarak ayarlandığında, StringBuilder'ınızın önüne eklediğiniz anlamına gelir.
StringBuilder sb = new StringBuilder();
for(int i=0;i<100;i++){
sb.insert(0,i);
}
NOT : ekleme yöntemi tüm ilkel türlerini kabul ettiğinden, int, long, char [] vb. İçin kullanabilirsiniz.
Peki ya:
StringBuilder builder = new StringBuilder();
for(int i=99;i>=0;i--){
builder.append(Integer.toString(i));
}
builder.toString();
VEYA
StringBuilder builder = new StringBuilder();
for(int i=0;i<100;i++){
builder.insert(0, Integer.toString(i));
}
builder.toString();
Ancak bununla O (N) yerine O (N ^ 2) işlemini yapıyorsunuz.
Java dokümanlarından pasaj:
Object bağımsız değişkeninin dize gösterimini bu karakter dizisine ekler. Genel etki, tıpkı ikinci bağımsız değişken, yöntem tarafından bir dizeye dönüştürülmüş
String.valueOf(Object)
ve bu dizenin karakterleri daha sonra belirtilen ofsette bu karakter dizisine eklenmiş gibidir.
AbstractStringBuilder
eklenenler için yer bulmak için tüm içeriği ekleme dizininin ötesine taşımayı sağlar. Ancak bu bir uygulama detayıdır, prensiplerden biri değildir.