[icono]Manual de Java Volver a índice

Capítulo 6. Gestión de cadenas.


Una cadena es una secuencia de caracteres. Las cadenas son una parte fundamental de la mayoría de los programas, así pues Java tiene varias características incorporadas que facilitan la manipulación de cadenas.

Java tiene una clase incorporada en el paquete java.lang que encapsula las estructuras de datos de una cadena. Esta clase, llamada String es la representación como objeto de una matriz de caracteres que no se puede cambiar.

Hay una clase que la acompaóa, llamada StringBuffer, que se utiliza para crear cadenas que pueden ser manipuladas después de ser creadas.

Constructores

Como con todas las otros clases, se pueden crear instancias de String con el operador new.

String s = new String();

Este ejemplo creara una instancia de String sin caracteres en ella. Para crear un String inicializado con caracteres hay que pasarle una matriz de char al constructor. Veamos un ejemplo:

char chars[] = { 'a','b','c'};
String s = new String(chars); // s es la cadena "abc"

Si se tiene una matriz de la que solo un rango nos interesa existe un constructor que permite especificar el índice de comienzo y el n§. de caracteres a utilizar.

char chars[] = {'a','b','c','d','e','f'};
String s = new String(chars, 2, 3); // s es la cadena "cde"

También existen constructores para caracteres ASCII (caracteres de 8 bits) frente a los caracteres Unicode de Java (caracteres de 16 bits).

Sintaxis de cadenas especial

Java incluye algunas ayudas sintácticas con el fin de ayudar a los programadores a realizar las operaciones mas habituales con cadenas.

Creación de cadenas

Dado que los Strings son valores constantes, Java incluye un atajo para un literal de cadena estándar, en el que un valor de cadena se puede encerrar entre comillas dobles:

String s = "abad";

uno de los métodos mas habituales que se utilizan en un String es length, que devuelve el n§. de caracteres de una cadena:

String s = "abc";
System.out.println(s.length()); // imprimiría 3

Un punto interesante en Java es que se crea una instancia de objeto para cada literal String, por lo que se puede llamar a los métodos directamente con una cadena entre comillas, como si fuera una referencia a objeto, con este ejemplo se volvería a imprimir un 3:

String s = "abc";
System.out.println("abc".lenght());

Concatenación de cadenas

El único operador que utiliza Java es + , y en los objetos String. El + actúa como operador de concatenación en este caso en concreto para mejorar la legibilidad, por ser operación muy común.

String s = "El tiene " + edad + " aņos";

esta mucho más claro que

String s = new StringBuffer("El tiene ")
		.append (edad)
		.append (" aņos")
		.toString();

que es lo que sucede cuando se ejecuta este código. append aóade cosas al final de StringBuffer, y toString convierte a cadenas el StringBuffer. Trataremos con detalle append y toString mas adelante en este capítulo.

Aspectos de precedencia de operadores

Debe tener cuidado cuando mezcle expresiones enteras con expresiones de concatenación de cadenas por que puede obtener resultados sorprendentes.

String s = "cuatro: " + 2 + 2;

Se podría esperar que el valor de s sea "cuatro: 4", pero la procedencia de operadores provoco que se evaluase primero la subexpresión "cuatro: " + 2, y después "cuatro: 2" + 2, donde como resultado "cuatro: 22". Si se desea realizar primero la expresión entera, hay que utilizar paréntesis, como aquí:

String s = "cuatro: " + (2+2);

Conversión de cadenas

StringBuffer tiene una versión sobrecargada de append para cada tipo posible. Por lo tanto, cuando se utiliza `+' para concatenar una variable, se llama a la versión adecuada de append para esa variable. El método append realmente llama a un método estático de String llamado valueOf para construir la representación tipo cadena. Para tipos simples, valueOf crea simplemente una representación de cada int o float. Para objetos, valueOf llama al método to String con ese objeto. Cada clase implementa toString, con una implementación por defecto que se encuentra en la clase Object. Es bueno el sobrescribir toString y presentar una versión propia de cadena para las clases. El ejemplo siguiente muestra una clase que sobrescribe toString para mostrar los valores de sus variables de instancia.

class Point {
	 int x, y;
	 Point(int x, int y)  {
		this.x = x;
		this.y = y;
	 }
	 public String toString()  {
		return "Punto[" + x + "," + y + "]";
	 }
}
class toStringDemo   {
	 public static void main(String args[])   {
		Point p = new Point(10, 20);
		System.out.println("p = " + p);
	 }
}

Esta versión de la clase Point de los capítulos anteriores incluye una versión con la que se sobrescribe el método toString del objeto, y que da formato a la cadena que contiene los valores de x y de y de cada instancia de Point. La salida de este programa es la siguiente:

c:\> java toStringDemo
p = Punto[10, 20 ]

Extracción de caracteres

Para extraer un único carácter de una cadena, se puede referir a un carácter indexado mediante el método charAt:

"abc".charAt(1) // devolverá 'b'

Si se necesita extraer más de un carácter a la vez, puede utilizar el método gerChars, que le permite especificar el índice del primer carácter y del último más uno que se desean copiar, además de la matriz char donde se desean colocar dichos caracteres.

String s = "Esto no es una canción";
char buf[] = new char[2];
s.getChars(5, 7, buf, 0); // buf ahora tendrá el valor 'no'

También existe una función útil llamada toCharArray, que devuelve una matriz de char que contiene la cadena completa.

Comparación

Si se desean comparar dos cadenas para ver si son iguales, puede utilizar el método equals de String. Devolverá true si el único parámetro está compuesto de los mismos caracteres que el objeto con el que se llama a equals. Una forma alternativa de equals llamada equalsIgnoreCase ignora si los caracteres de las cadenas que se comparan están en mayúsculas o minúsculas.

La clase String ofrece un par de métodos útiles que son versiones especializadas de equals. El método reginMatches se utiliza para comparar una región especifica que se parte de una cadena con otra región de otra cadena. Hay dos variantes de regionMatches, una le permite controlar si es importante la diferenciación entre mayúsculas/minúsculas; la otra asume que si lo es.

boolean regionMatches (int toffset, String otra, 
			int ooffset, int longitud); // si importa la diferencia
boolean regionMatches (boolean ignorarMaysc,
			int toffset, String otra,
			int ooffset, int longitud); // no importa la diferencia

En estas dos versiones de regionMatches, el parámetro toffset indica el desplazamiento en caracteres en el objeto String sobre el que estamos llamando el método. La cadena con la que estamos comparando se llama otra, y el desplazamiento dentro de esa cadena se llama ooffset. Se comparan longitud caracteres de las dos cadenas comenzando a partir de los dos desplazamientos.

Igualdad

El método equals y el operador = = hacen dos pruebas completamente diferentes para la igualdad. Mientras que el método equals compara los caracteres contenidos en una String, el operador = = compara dos referencias de objeto para ver si se refieren a la misma instancia.

Ordenación

A menudo no basta con conocer si dos cadenas son idénticas o no. Para aplicaciones de ordenación, necesitamos conocer cuál es menor que, igual que o mayor que la siguiente. El método de String compareTo se puede utilizar para determinar la ordenación. Si el resultado entero de compareTo es negativo, la cadena es menor que el parámetro, y si es positivo, la cadena es mayor. Si compareTo devuelve 0, entonces las dos cadenas son iguales. Ahora ordenaremos una matriz de cadenas utilizando compareTo para determinar el criterio de ordenación mediante una Ordenación en burbuja.

class SortString {
	static String arr[] = {
		"Ahora", "es", "el ", "momento", "de", "actuar"
	};
	public static void main(String args[])  {
		for (int j = 0; j < arr.length; j++) {
			for (int i = j + 1; i < arr.length; y++) {
				if (arr[i].compareTo(arr[j] < 0) {
				   String t = arr[j];
				   arr[j] = arr[i];
				   arr[i] = t;
				}
			}
			System.out.println(arr[j]);
		}
	}
}

valueOf

Si se tiene algún tipo de datos y se desea imprimir su valor de una forma legible, primero hay que convertirlo a String. El método valueOf está sobrecargado en todos los tipos posibles de Java, por lo que cada tipo se puede convertir correctamente en una String. Cualquier objeto que se le pase a valueOf devolverá el resultado de llamar al método toString del objeto. De hecho, se podría llamar directamente a toString y obtener el mismo resultado.

StringBuffer

StringBuffer es una clase gemela de String que proporciona gran parte de la funcionalidad de la utilización habitual de las cadenas. StringBuffer representa secuencias de caracteres que se pueden ampliar y modificar. Java utiliza ambas clases con frecuencia, pero muchos programadores sólo tratan con String y permiten que Java manipule StringBuffer por su cuenta mediante el operador sobrecargado '+'.

append

Al método append de StringBuffer se le llama a menudo a través del operador +. Tiene versiones sobrecargadas para todos los tipos. Se llama a String.valueOf para cada parámetro y el resultado se aóade al StringBuffer actual. Cada versión de append devuelve el propio buffer.