2010-07-06 9 views
13

bemerkte ich, dass die capacity Methode gibt StringBuilder Kapazität ohne Logik Art und Weise ... irgendwann sein Wert ist gleich der Stringlänge andermal es größer ist ...String Kapazität()

es für Know eine Gleichung ist Welches ist seine Logik?

+0

Warum interessiert dich die "Kapazität"? Es wächst automatisch, um alles Notwendige aufzunehmen. Sie können damit spielen, um die Leistung zu verbessern, aber es ist immer noch asymptotisch linear. – polygenelubricants

+5

Es gibt Fragen über "Kapazität" im Vergleich zu "Länge" in der OCA-Prüfung, so dass für manche Leute das Problem eine Menge bedeutet. –

Antwort

3

Diese Funktion macht etwas anderes als Sie erwarten - es gibt Ihnen die maximale Anzahl von Zeichen, die dieser StringBuilder-Instanzspeicher zu diesem Zeitpunkt enthalten kann.

String Builder must read

+0

+1 für den netten Link – codebox

1

EDIT: Apologies - die unten Informationen über .NET die String und ist nicht unbedingt relevant für die ursprüngliche Frage.

http://johnnycoder.com/blog/2009/01/05/stringbuilder-required-capacity-algorithm/

String reserviert Speicherplatz für Substrings Sie es vielleicht hinzufügen (viel wie List Raum das Array schafft es wickelt). Wenn Sie die tatsächliche Länge der Zeichenfolge möchten, verwenden Sie StringBuilder.Length.

+0

Dieser Artikel handelt von C#, nicht wahr? –

+0

Ja. Die Formel ähnelt Java, ist aber nicht genau dieselbe. – Catchwa

+1

Ich entschuldige mich - ich sah StringBuilder und nahm .NET an. –

12

Wenn Sie zu StringBuilder anhängen, wird die folgende Logik geschieht:

if (newCount > value.length) { 
    expandCapacity(newCount); 
} 

wo newCount die Anzahl der Zeichen ist erforderlich, und value.length die aktuelle Größe des Puffers ist.

expandCapacity erhöht einfach die Größe des Trägers char[]

Die ensureCapacity() Methode ist der öffentliche Weg expandCapacity() zu nennen, und seine docs sagen:

Stellen sicher, daß die Kapazität mindestens gleich den spezifizierte Minimum. Wenn die aktuelle Kapazität kleiner als das Argument ist, wird ein neues internes Array mit größerer Kapazität zugewiesen. Die neue Kapazität ist die größere von:

  • Das Argument minimumCapacity.
  • Zweimal die alte Kapazität plus 2.

Wenn das minimumCapacity Argument ist kraft-, nimmt diese Methode keine Aktion und einfach zurückgibt.

+1

ja, aber wenn ich habe: StringBuilder str = new StringBuilder(); // Kapazität 16 str.anhängen ("1111111111111111111"); Kapazität 32 Länge 19 Laut der Gleichung, warum die Kapazität nicht 16 * 2 + 2 = 34 ?? – xdevel2000

1

Von der API:

hat Jeder String-Builder eine Kapazität. Solange die Länge des Zeichens Sequenz in der Zeichenfolge Builder die Kapazität nicht überschreitet, ist es nicht erforderlich, einen neuen internen Puffer zu reservieren. Wenn der interne Puffer überläuft, wird automatisch größer gemacht.

Wenn Sie etwas anzuhängen, wird geprüft, um sicherzustellen, dass die aktualisierte String nicht seine Kapazität übersteigt, und wenn ja, der interne Speicher des String Größe geändert wird:

int len = str.length(); 
int newCount = count + len; 
if (newCount > value.length) 
    expandCapacity(newCount); 

wenn Daten, die ihm hinzugefügt wird, dass seine Kapazität übersteigt es erneut bemessen nach der folgenden Formel:

void expandCapacity(int minimumCapacity) { 
int newCapacity = (value.length + 1) * 2; 
    if (newCapacity < 0) { 
     newCapacity = Integer.MAX_VALUE; 
    } else if (minimumCapacity > newCapacity) { 
    newCapacity = minimumCapacity; 
} 
    value = Arrays.copyOf(value, newCapacity); 
} 

Siehe src.zip-Datei, die für mehr informati mit dem JDK kommt auf. (Über Schnipsel aus dem 1.6 JDK)

+1

In JDK 7 Quelle gibt es nicht mehr + 2 Zeichen nur den neuen Wert * 2 !!! – xdevel2000

+0

Interessant! Vielleicht haben sie es als Optimierung herausgenommen? – Catchwa

+0

Vielleicht, aber in die jdk 7 Dokumentation, die noch nicht aktualisiert ist! – xdevel2000

10

Ich werde versuchen, dies mit einem Beispiel zu erklären.

public class StringBuilderDemo { 
    public static void main(String[] args) { 
     StringBuilder sb = new StringBuilder(); 
     System.out.println(sb.length()); 
     System.out.println(sb.capacity()); 
    } 
} 

length() - die Länge der Zeichenfolge im Builder da diese Stringbuilder keine Inhalte enthalten, wird seine Länge 0.

capacity() sein - die Anzahl der Zeichenräume, die zugeteilt wurden . Wenn Sie versuchen, einen Zeichenfolgengenerator mit leerem Inhalt zu erstellen, wird standardmäßig die Initialisierungsgröße als Länge + 16 verwendet, die 0 + 16 ist. So würde die Kapazität 16 hier zurückkehren.

Hinweis: Die Kapazität, die von der capacity() -Methode zurückgegeben wird, ist immer größer oder gleich der Länge (normalerweise größer als) und wird automatisch erweitert, wenn Erweiterungen des Zeichenfolgengenerators erforderlich sind.

Die Logik hinter der Kapazitätsfunktion:

  1. Wenn Sie initialisieren nicht Stringbuilder mit beliebigem Inhalt, werden Standardkapazität als 16 Zeichen Kapazität genommen werden.
  2. Wenn Sie Stringbuilder mit einem Inhalt initialisieren, hat die Kapazität die Inhaltslänge + 16.
  3. Wenn Sie dem stringbuilder-Objekt neuen Inhalt hinzufügen, wenn die aktuelle Kapazität nicht ausreicht, um einen neuen Wert zu erhalten, wird sie um (vorherige Array-Kapazität + 1) * 2 erhöht.

Diese Analyse nehmen von actual StringBuilder.java code

0

Sie innerhalb des JDK Code gehen und sehen, wie es funktioniert, ist es auf einem char-Array basiert: new char[capacity], ist es ähnlich wie bei den ArrayList Werke (When to use LinkedList over ArrayList?) . Beide verwenden Arrays als "hardware-effizient", der Trick besteht darin, einen großen Teil des Speichers zuzuordnen und darin zu arbeiten, bis der Speicher aufgebraucht ist und der nächste große Block zum Fortsetzen (Erweitern/Vergrößern) benötigt wird.

Verwandte Themen