StringBuilder y StringBuffer son dos clases de uso común para manipular cadenas. Como todos sabemos, StringBuilder es Insecure de Thread, mientras que StringBuffer es seguro de hilo. El primero fue agregado por JDK1.5, y el segundo estaba disponible en JDK1.0. Analicemos sus implementaciones internas a continuación.
1. Relación de herencia
public Final Clase StringBuffeTextends AbstractStringBuilderImplements java.io.Serializable, CharSECECEPublic de clase final StringBuildExtends AbstractStringBuilderImplements java.io.Serializable, CharSECHEQUI
Se puede ver que la relación de herencia entre las dos clases es exactamente la misma. Serializable es una bandera serializable. La interfaz CharSequence incluye métodos Charat (), longitud (), subsecuencias () y toString (). La clase de cadena también implementa esta interfaz. El enfoque aquí está en la clase abstracta AbstractStringBuilder, que encapsula la implementación de la mayoría de las operaciones de StringBuilder y StringBuffer.
2. AbstractStringBuilder
1. Variables y métodos de construcción
char [] value; int count; abstractStringBuilder () {} AbstractStringBuilder (int capacidad) {valor = nuevo char [capacidad];}AbstractStringBuilder utiliza una matriz Char [] para guardar cadenas, y el método de capacidad inicial se puede especificar durante la construcción.
2. Expandir la capacidad
public void setureCapacity (int mínimoCapacity) {if (mínimoCapacity> 0) setureCapacityInternal (mínimoCapacity);} private void setureCapacityInternal (int mínimoCapacity) {// código de desbordamiento -consciente if (mínimocapacidad - valor.lengthing> 0) expandel mínimoCapacity) {int newCapacity = value.length * 2 + 2; if (newCapacity - MinimumCapacity <0) NewCapacity = MinimumCapacity; if (newCapacity <0) {if (mínimo de capacidad <0) // desbordamiento tirar nueva outOfMemoryError (); newCapacity = Integer.max_value; } value = arrays.copyOf (valor, newCapacity);}El método de expansión se implementa en última instancia por expandcapacity (). En este método, la capacidad primero se expande a la capacidad original más 2. Si aún es menor que la capacidad especificada en este momento, entonces la nueva capacidad se establece con capacidad mínima. Luego determine si está desbordando. Si está desbordando, establezca la capacidad de entero.max_value. Finalmente, copiar el valor del valor es obviamente una operación que requiere mucho tiempo.
3. Método append ()
public AbstractStringBuilder append (String Str) {if (str == null) return appendNull (); int len = str.length (); EnsurecapacityInternal (recuento + len); str.getChars (0, len, valor, recuento); recuento += len; devolver esto; }append () es el método más utilizado, tiene muchas formas de sobrecarga. Lo anterior es uno de ellos, que se usa para agregar cadenas. Si STR es nulo, se llamará al método appendNull (). Este método en realidad agrega caracteres como 'N', 'U', 'L' y 'L'. Si no es nulo, primero expanda la capacidad y luego llame al método getChars () de cadena para agregar STR al final del valor. Finalmente, se devuelve el objeto en sí, por lo que append () puede llamarse continuamente.
3. StringBuilder
AbstractStringBuilder ha implementado la mayoría de los métodos requeridos, y StringBuilder y StringBuffer solo necesitan llamarse. Echemos un vistazo a la implementación de StringBuilder.
1. Constructor
public StringBuilder () {super (16);} public StringBuilder (int capacidad) {super (capacidad);} public StringBuilder (String Str) {super (str.length () + 16); append (str);} public stringBuilder (charsequence seq) {this (seq.length () + 16); append (seq);}Como se puede ver, el tamaño de capacidad predeterminado de StringBuilder es 16. Por supuesto, también puede especificar la capacidad inicial o asignar el valor inicial al objeto StringBuilder en una secuencia existente de caracteres.
2. Método append ()
public StringBuilder append (string str) {super.append (str); devolver esto;} public StringBuilder append (CharSequence S) {super.append (s); devolver esto;}Hay muchos métodos de sobrecarga para append (), y aquí hay dos de ellos. Obviamente, aquí está el método en la clase principal AbstractStringBuilder que se llama directamente.
3. Tostring ()
public String toString () {// Crear una copia, no comparta la matriz devuelve la nueva cadena (valor, 0, count);}El método toString () devuelve un nuevo objeto de cadena que no comparte memoria con el objeto original. De hecho, lo mismo es cierto para el método Substring () en AbstractStringBuilder.
4. Sringbuffer
StiringBuffer es similar a StringBuilder, pero para lograr la sincronización, muchos métodos usan modificaciones lyncronizadas, como el siguiente método:
public sincronizado int long () {return count;} public Syncronized StringBuffer append (String Str) {toStringCache = null; super.append (str); devolver esto;} public sincronizado void setLength (int newLength) {toStringCache = null; super.setLength (newLength);} Como puede ver, el sincronizado se agrega delante del método.
Además, también hay un tostringcache variable en los métodos append () y setLength () anteriores. Esta variable se usa para el último caché del método toString (). Cada vez que se modifica StringBuffer, esta variable se asignará a NULL. La tostración de StringBuffer es la siguiente:
public sincronized String toString () {if (toStringCache == null) {toStringCache = arrays.copyOfRange (valor, 0, count); } return new String (ToStringCache, true);}En este método, si ToStringCache es nulo, se almacena en caché primero. El objeto final de cadena devuelto es un poco diferente, y este constructor tiene un parámetro verdadero. Encuentre el código fuente de cadena y eche un vistazo:
String (Char [] valor, boolean share) {// afirmar compartir: "no compartido no admitido"; this.Value = value;}Resulta que el objeto de cadena construido por este método de construcción en realidad no copia la cadena, sino que solo apunta el valor a los parámetros de construcción, que es ahorrar elementos de copia de tiempo. Sin embargo, este constructor tiene permisos de acceso al paquete y no puede llamarse en general.
Resumir
Lo anterior se trata de este artículo. Espero que sea útil para todos aprender dos clases de cadenas operativas de uso común en Java, StringBuilder y StringBuffer.