Tutorial de Java

Clases Java

Anterior | Siguiente
La Clase StringBuffer

Java posee gran capacidad para el manejo de cadenas dentro de sus clases String y StringBuffer. Un objeto String representa una cadena alfanumérica de un valor constante que no puede ser cambiada después de haber sido creada. Un objeto StringBuffer representa una cadena cuyo tamaño puede variar.

La clase StringBuffer dispone de muchos métodos para modificar el contenido de los objetos StringBuffer. Si el contenido de una cadena va a ser modificado en un programa, habrá que sacrificar el uso de objetos String en beneficio de StringBuffer, que aunque consumen más recursos del sistema, permiten ese tipo de manipulaciones.

Al estar la mayoría de las características de los StringBuffers basadas en su tamaño variable, se necesita un nuevo método de creación:

StringBuffer();
StringBuffer( int length );
StringBuffer( String str );

Se puede crear un StringBuffer vacío de cualquier longitud y también se puede utilizar un String como punto de partida para un StringBuffer.

StringBuffer Dos = new StringBuffer( 20 );
StringBuffer Uno = new StringBuffer( "Hola Mundo" );
StringBuffer Cero = new StringBuffer();

Parece, aparentemente, más efectivo si se conoce la longitud final del objeto, indicarla cuando se instancia el objeto, que dejar que el sistema instancie el objeto con una longitud por defecto y luego hacer que se incremente, en tiempo de ejecución, cuando se manipule el objeto. Esto se muestra en las siguientes sentencias, que utilizan el método length() de la clase String para hacer las cosas más interesantes (un simple entero indicando el tamaño del objeto StringBuffer hubiese funcionado igualmente).

StringBuffer str = new StringBuffer( 
    "StringBuffer de prueba".length() );
Str.append( "StringBuffer de prueba" );

Cambio de Tamaño

El cambio de tamaño de un StringBuffer necesita varias funciones específicas para manipular el tamaño de las cadenas:

int length();
char charAt( int index );
void getChars( int srcBegin,int srcEnd,char dst[],int dstBegin );
String toString();
void setLength( int newlength );
void setCharAt( int index,char ch );
int capacity();
void ensureCapacity( int minimumCapacity );
int reverse();

Observar que una de las funciones devuelve una cadena constante normal de tipo String. Este objeto se puede usar con cualquier función String, como por ejemplo, en las funciones de comparación.

El método capacity() es particularmente interesante, ya que devuelve la cantidad de espacio que hay actualmente reservado para el objeto StringBuffer, en contraposición al método length(), que devuelve la cantidad de espacio ocupado por el objeto StringBuffer.

Modificación del Contenido

Para cambiar el contenido de un StringBuffer, se pueden utilizar dos métodos: append() e insert().

En el ejemplo java807.java, vemos el uso de estos dos métodos:

class java807 {
    public static void main( String args[] ) {
        StringBuffer str = new StringBuffer( "Hola" );
        str.append( " Mundo" );

        System.out.println( str );
        }
    }

En este otro ejemplo, java808.java, mostramos un método muy simple que le da la vuelta a una cadena:

class java808 {
    public static String cadenaInversa( String fuente ) {
        int longitud = fuente.length();

        StringBuffer destino = new StringBuffer( longitud );
        
        for( int i=(longitud-1); i >= 0; i-- )
            destino.append( fuente.charAt( i ) );

        return( destino.toString() );
        }

    public static void main( String args[] ) {
        System.out.println( cadenaInversa( "Hola Mundo" ) );
        }
    }

Las funciones que cambian el tamaño son pues:

StringBuffer append( Object obj );
StringBuffer append( String str );
StringBuffer append( char str[] );
StringBuffer append( char str[],int offset,int len );
StringBuffer append( boolean b );
StringBuffer append( int i );
StringBuffer append( long l );
StringBuffer append( float f );
StringBuffer append( double d );
StringBuffer append( char c );
StringBuffer insert( int offset,Object obj );
StringBuffer insert( int offset,String str );
StringBuffer insert( int offset,char str[] );
StringBuffer insert( int offset,boolean b );
StringBuffer insert( int offset,int i );
StringBuffer insert( int offset,long l );
StringBuffer insert( int offset,float f );
StringBuffer insert( int offset,double d );
StringBuffer insert( int offset,char c );

Operadores de Concatenación

Hay que recordar que los operadores " +" y " +=" también se pueden aplicar a cadenas. Ambos realizan una concatenación y están implementados con objetos StringBuffer.

Por ejemplo, la sentencia:

String s = "¿Qué" + " tal ?";

es interpretada por el compilador como:

String s = 
    new StringBuffer().append( "¿Qué" ).append( " tal ?" 
    ).toString();

y se marcaría el StringBuffer para borrarlo ya que el contenido pasa al objeto String. También, la sentencia:

s += " por ahí!" ;

sería interpretada por el sistema como:

String s = 
    new StringBuffer().append( s ).append( " por ahí!" ).toString();

y volvería a marcar para borrar el nuevo StringBuffer.

A continuación se muestran algunos ejemplos de utilidad de estas funciones. En el applet java809.java, que se muestra en el código que sigue, se usan estas funciones para producir una salida útil en un programa, presentando las coordenadas en las que se ha hecho click con el botón del ratón.

import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

// Este applet muestra la conversión de los enteros correspondientes a la
// posición en que se pulsa el ratón, a cadenas para poder mostrar en
// pantalla esas posiciones
public class java809 extends Applet {
    int RatonX = 25;
    int RatonY = 25;
    String Status = "Pulsa un botón del ratón";

    public java809() {
        ProcesoRaton procesoRaton = new ProcesoRaton();
        addMouseListener( procesoRaton );
        }

    public void paint( Graphics g ) {
        g.drawString( Status,RatonX,RatonY );
        }

    // Cuando se pulsa el ratón se presentarán en pantalla las
    // coordenadas de la posición en que se ha pulsado
    // Esta es una Clase Anidada
    class ProcesoRaton extends MouseAdapter {
      public void mousePressed( MouseEvent evt ) {
        // Recoge las coordenadas X e Y de la posicion del cursor
        // y las almacena
        RatonX = evt.getX();
        RatonY = evt.getY();

        Integer X = new Integer( RatonX );
        Integer Y = new Integer( RatonY );
        Status = X.toString()+","+Y.toString();
        // Finalmente, presenta los valores de las coordenadas
        repaint();
        }
      }
    }

En el ejemplo java810.java, se muestran diversas formas de crear e instanciar tanto objetos String como objetos StringBuffer.

Y el ejemplo java811.java, trata de hacer comprender al lector la diferencia entre la utilización de la clase String y la clase StringBuffer. El programa trata de quitar los tabuladores de un texto, convirtiéndolos en espacios. Se supone que es necesario formatear así el texto para presentarlo luego en pantalla, utilizando un método como drawString(), que no soportaría la presencia de tabuladores.

Una forma de resolver el problema sería partir de una cadena vacía e ir incorporando caracteres utilizando el operador += , tal como se muestra en las siguientes líneas de código:

    String resultado = "";
    ...
    resultado += 'x';

Esto funciona, pero no tiene en cuenta el hecho de que en Java los objetos String son inmutables, es decir, nunca pueden cambiar. Por lo tanto, lo que en realidad suponen las líneas anteriores es que el valor actual de resultado se copie a un buffer temporal, se le añada el carácter y se cree un nuevo objeto String que es el que se va a referenciar. Otra forma de decir esto sería:

    String cadena1 = "abc";
    String cadena2 = cadena1;

    cadena1 = "xyz";
    System.out.println( cadena2 );

La salida, o el resultado, será "abc", porque la reasignación a cadena1, no cambia la referencia de cadena2 a la cadena "abc".

Una forma mucho más rápida de resolver el problema consiste en la utilización de StringBuffer, que sí soporta la modificación de cadenas. Operaciones como añadir están directamente soportadas en StringBuffer y el resultado puede ser convertido a un String en cualquier momento. El ejemplo utiliza los dos métodos, quitaTab1() sustituye los tabuladores utilizado String y quitaTab2() hace la misma operación utilizando StringBuffer.

El programa java811.java comprueba los datos para asegurarse de que son equivalentes, para luego comparar el tiempo que tarda la ejecución por ambos métodos. El segundo método, que utiliza StringBuffer, corre unas seis veces más rápido que el método que usa String.

Cuando se estén optimizando programas con una gran cantidad de procesado de textos, es siempre una buena idea el mantener en mente el trabajo que se realiza sobre cada carácter, y el ejemplo anterior sirve para que el lector compruebe la diferencia que se puede conseguir a la hora de manipular eficientemente las posibilidades que ofrece el lenguaje Java.

La Clase StringTokenizer

La clase StringTokenizer proporciona uno de los primeros pasos para realizar un análisis gramatical de una cadena de entrada, extrayendo los símbolos que se encuentren en esa cadena. Si se tiene una cadena de entrada cuyo formato es regular y se desea extraer la información que está codificada en ella, StringTokenizer es el punto de partida.

Para utilizar esta clase, se necesita un String de entrada y un String de delimitación. Los delimitadores marcan la separación entre los símbolos que se encuentran en la cadena de entrada. Se considera que todos los caracteres de la cadena son delimitadores válidos; por ejemplo, para <,;:> el delimitador puede ser una coma, un punto y coma o dos puntos. El conjunto de delimitadores por defecto son los caracteres de espacio habituales: espacio, tabulador, línea nueva y retorno de carro.

Una vez que se ha creado un objeto StringTokenizer, se utiliza el método nextToken() para ir extrayendo los símbolos consecutivamente. El método hasMoreTokens() devuelve true cuando todavía quedan símbolos por extraer.

En el ejemplo java812.java se crea un objeto StringTokenizer para analizar gramaticalmente parejas del tipo " clave=valor" de un String. Los conjuntos consecutivos de parejas clave=valor, van separadas por dos puntos ( :)

import java.util.StringTokenizer;

class java812 {
    static String cadena = "titulo=Tutorial de Java:" +
        "idioma=castellano:" +
        "autor=Agustin Froufe:" +
        "e-mail=froufe@arrakis.es";

    public static void main( String args[] ) {
        StringTokenizer st = new StringTokenizer( cadena,"=:" );

        while( st.hasMoreTokens() ) {
            String clave = st.nextToken();
            String valor = st.nextToken();

            System.out.println( clave + "\t" + valor );
            }
        }
    }

Y la salida de este programita tan sencillo, una vez ejecutado se presenta en la reproducción siguiente:

C:\> java java812
titulo  Tutorial de Java
idioma  castellano
autor   Agustin Froufe
e-mail  froufe@arrakis.es

Navegador

Home | Anterior | Siguiente | Indice | Correo