2010-07-06 8 views
13

Je remarque que la méthode capacity retourne la capacité StringBuilder sans logique façon ... quelque temps sa valeur est à la longueur est égale à cordes autre temps est plus ...capacité StringBuilder()

est là une équation pour le savoir quelle est sa logique?

+0

Pourquoi vous souciez-vous de la 'capacité '? Il se développe automatiquement pour accommoder tout ce qui est nécessaire. Vous pouvez jouer avec pour améliorer la performance, mais c'est toujours asymptotiquement linéaire. – polygenelubricants

+5

Il y a des questions sur la «capacité» par rapport à la «longueur» dans l'examen OCA, donc pour certaines personnes, le problème signifie beaucoup. –

Répondre

3

Cette fonction fait quelque chose de différent de ce que vous attendez - elle vous donne le nombre maximum de caractères que la mémoire de l'instance StringBuilder peut contenir à ce moment.

String Builder must read

+0

+1 pour le lien sympa – codebox

1

EDIT: Toutes mes excuses - le ci-dessous des informations sur StringBuilder de .NET, et ne sont pas strictement à la question initiale.

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

StringBuilder alloue de l'espace pour que vous pourriez ajouter des sous-chaînes à elle (un peu comme la liste crée un espace du tableau, il enveloppe). Si vous voulez la longueur réelle de la chaîne, utilisez StringBuilder.Length.

+0

Cet article parle de C#, n'est-ce pas? –

+0

Oui. La formule est similaire à Java mais pas exactement la même chose. – Catchwa

+1

Mes excuses - J'ai vu StringBuilder et supposé .NET. –

12

Lorsque vous ajoutez à la StringBuilder, la logique suivante se produit:

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

newCount est le nombre de caractères nécessaires et value.length est la taille actuelle de la mémoire tampon.

expandCapacity augmente simplement la taille du support char[]

La méthode ensureCapacity() est la voie publique pour appeler expandCapacity(), et ses documents dire:

assure que la capacité est au moins égale à celle spécifiée le minimum. Si la capacité actuelle est inférieure à l'argument, un nouveau tableau interne est alloué avec une capacité supérieure. La nouvelle capacité est la plus grande de:

  • L'argument minimumCapacity.
  • deux fois l'ancienne capacité, plus 2.

Si l'argument est minimumCapacity non positive, cette méthode ne prend aucune mesure et retourne simplement.

+1

oui mais si j'ai: StringBuilder str = new StringBuilder(); // capacité 16 str.ajouter ("1111111111111111111"); capacité 32 longueur 19 Selon l'équation pourquoi la capacité n'est pas 16 * 2 + 2 = 34 ?? – xdevel2000

1

de l'API:

Chaque constructeur de chaîne a une capacité. Tant que la longueur du caractère séquence contenue dans le générateur de chaîne ne dépasse pas la capacité, il n'est pas nécessaire d'allouer un nouveau tampon interne . Si le tampon interne déborde, il est automatiquement augmenté de .

Chaque fois que vous ajoutez quelque chose, il y a un chèque pour vous assurer que la mise à jour StringBuilder ne dépassera pas sa capacité, et si elle le fait, le stockage interne de l'StringBuilder est redimensionnée:

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

lorsque les données sont ajoutées à ce qui dépasse sa capacité, il est redimensionnée selon la formule suivante:

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); 
} 

Voir le fichier src.zip qui vient avec le JDK pour plus informati sur. (Au-dessus des extraits extraits du 1.6 JDK)

+1

Dans la source JDK 7 il n'y a plus + 2 caractères que la nouvelle valeur * 2 !!! – xdevel2000

+0

Intéressant! Peut-être qu'ils l'ont pris comme une optimisation? – Catchwa

+0

Peut-être, cependant, dans la documentation de jdk 7 qui n'est pas encore mise à jour! – xdevel2000

10

Je vais essayer d'expliquer ceci avec quelques exemples.

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

length() - la longueur de la séquence de caractères dans le générateur puisque ce stringbuilder ne contient aucun contenu, sa longueur sera 0.

capacity() - le nombre de places de caractères qui ont été attribués . Lorsque vous essayez de construire un Stringbuilder avec du contenu vide, il prend par défaut la taille de l'initialisation en tant que length + 16, soit 0 + 16. donc la capacité reviendrait 16 ici.

Remarque: La capacité, renvoyée par la méthode capacity(), est toujours supérieure ou égale à la longueur (généralement supérieure à) et s'étendra automatiquement si nécessaire pour prendre en compte les ajouts au générateur de chaînes.

La logique derrière la fonction de la capacité:

  1. Si vous n'initialisez pas stringbuilder avec tout contenu, la capacité par défaut sera prise comme capacité 16 caractères.
  2. Si vous initialisez stringbuilder avec n'importe quel contenu, la capacité sera de longueur +16.
  3. Lorsque vous ajoutez un nouveau contenu à l'objet stringbuilder, si la capacité actuelle n'est pas suffisante pour prendre une nouvelle valeur, elle augmente (capacité de la matrice précédente + 1) * 2.

Cette analyse est extrais actual StringBuilder.java code

0

Vous pouvez aller à l'intérieur du code JDK et voir comment cela fonctionne, il est basé sur un tableau de caractères: new char[capacity], il est semblable à la façon dont les ArrayList œuvres (When to use LinkedList over ArrayList?) . Les deux utilisent des tableaux pour être efficaces sur le plan matériel, l'astuce consiste à allouer un gros morceau de mémoire et à y travailler jusqu'à ce que vous manquiez de mémoire et que vous ayez besoin du prochain gros morceau pour continuer (agrandir/agrandir).