You are on page 1of 12

TEMA 6: STRINGS, I/O, FORMATEANDO Y PARSEANDO

TEMA 6: STRINGS, I/O, FORMATEANDO Y PARSEANDO 1.1 String, StringBuilder y StringBuffer. 1.1.1 String 1.1.1 StringBuffer y StringBuilder 2.1. File I/O. 2.1.1. Acceso a la entrada/salida estndar a travs de la clase System. 2.2. Acceso sobre ficheros 2.3. Serializando utilizando el paquete java.io. 2.4. Trabajando con fechas, nmeros y monedas: Calendar, dateFormat, date, locale, numberFormat 2.5. Expresiones regulares.

1.1 String, StringBuilder y StringBuffer.


Para tratar cadenas alfanumricas, en Java 1.6 existen tres tipos de clases principales: String, StringBuilder, StringBuffer. A continuacin, vamos a comentar las tres clases:

1.1.1 String
La principal caracterstica y diferencia con respecto a StringBuilder y StringBuffer es que String no puede modificarse de manera intrnseca. Es decir, las operaciones que realicemos sobre una clase String modificar el trozo de memoria reservado para el mismo. El siguiente ejemplo es bastante descriptivo:
package es.scjp.javahispano.tema6; public class P61Strings { /** * @param args */ public static void main(String[] args) { // EJEMPLO CON STRING String a = new String("JAIME"); // a vale Jaime y hay un trozo en // memoria con la constante nAIMEy un // puntero que apunta a ella. a = new String("JOSE"); // a vale Jose y hay dos trozo en memoria, uno // con la constante nAIMEy otro con la // constante nOSE apuntando la variable a a // nOSE a.concat(" ANTONIO"); // a sigue valiendo Jose y hay tres trozos // ocupados en memoria, "JAIME", "JOSE" y // "ANTONIO". // IMPORTANTE: los Strings no se modifican en s mismos System.out.println(a); // Sin embargo, lo siguiente asigna a la variable a "JOSE ANTONIO", pues // asigna valores a = a.concat(" ANTONIO"); System.out.println(a); // En las siguientes lneas, vemos como StringBuffer y StringBuilder // pueden modificarse de manera intrnseca, sin necesidad de asignarlos // de nuevo a una variable

StringBuffer stringBuffer = new StringBuffer("JOSE"); stringBuffer.append(" ANTONIO"); System.out.println("Valor de StringBuffer " + stringBuffer); StringBuilder stringBuilder = new StringBuilder("JOSE"); stringBuilder.append(" ANTONIO"); System.out.println("Valor de StringBuilder " + stringBuilder); } }

Cuando se define un valor String, se reserva un trozo de memoria, y se rellena con los valores indicados. La variable que ha creado el String, si ha habido alguna, apunta al mismo. El String no se puede modificar en si mismo. Esto es, el valor definido en la memoria de Java no es modificable en smismo, pudindose crear valores derivados del mismo, que ocupan su lugar en la memoria. Por ejemplo, en el siguiente cdigo:
java.lang.String a = "hello"; System.out.println(a); a = "jaime"; System.out.println(a);

En la lnea 4 tendremos una variable a, que apunta a un trozo de la memoria de Java que define una constante Jaime y despus, tendremos una variable en la memoria, que no es referenciada por ninguna variable. Sin embargo, vemos en el cdigo anterior que para modificar la variable a tendremos que reasignarla de manera contina a la misma variable o bien a otra. Lo que trato de decir es que, en este caso, el String referenciado no puede modificarse en si mismo, al ser realmente el String un trozo de memoria almacenado en la pila de memoria de Java, y ser la variable que lo apunta, en este caso, una variable que apunta a este trozo de memoria, y no tener privilegios sobre la misma que servir de apuntadora. La clase String tiene los siguientes mtodos importantes a tener en cuenta: -charAt: devuelve el carcter que se encuentra en una posicin determinada. -indexOf:permite devolver el ndice de un carcter. -isEmpty: permite determinar si el String est vaco o no. -length: permite calcular la longitud del String. ES IMPORTANTE NO CONFUNDIR length de String con size de array.

1.1.1 StringBuffer y StringBuilder


Este caso, sin embargo, no pasa con StringBuffer. StringBuffer y StringBuilder son dos clases bastante similares: ambas se han definido para gestionar el manejo de cadenas en Java. Sin embargo,

desde la JDK 1.5 se define StringBuilder, que contiene los mismos mtodos que StringBuffer, con la diferencia de que sus mtodos no estn sincronizados y por lo tanto no tienen restricciones a nivel concurrente. No entraremos en detalle en esta caracterstica, simplemente diremos que la consecuencia de esto es que StringBuilder es mucho mn rnido que StringBuffer, y en los casos donde el rendimiento sea prioritario, se recomienda el uso del mismo en la mayora de los casos, pues normalmente no tendremos que tratar problemas de concurrencia. Veamos el siguiente ejemplo: long tiempoInicio = System.currentTimeMillis(); for (int i = 0; i < 25000; i++) { // String aux = ""+i; StringBuffer strbuf = new StringBuffer(); strbuf.append(i); } long totalTiempo = System.currentTimeMillis() - tiempoInicio; System.out.println("El tiempo de demora es :" + totalTiempo + " miliseg"); El tiempo de demora es :28 miliseg Sin embargo, en el caso de StringBuilder, vemos lo siguiente: tiempoInicio = System.currentTimeMillis(); for (int i = 0; i < 25000; i++) { // String aux = ""+i; StringBuilder strbuilder = new StringBuilder(); strbuilder.append(i); } totalTiempo = System.currentTimeMillis() - tiempoInicio; System.out.println("El tiempo de demora es :" + totalTiempo + " miliseg"); El tiempo de demora es :18 miliseg

En este ejemplo hemos podido comprobar que StringBuilder es mucho mn rniido que StringBuffer. Los mtodos ms relevantes de estas dos clases son los siguientes: -append: el valor pasado como parmetro desde el carcter final ocupado. -delete: elimina las casillas de los valores indicados por ndice. -insert: inserta desde la posicin indicada los valores pasados como parmetro. -replace: sustituye en los ndices adecuados el String pasado como parmetro. -setCharAt: establece en la posicin indicada el carcter especificado. -reverse: invierte el orden de las posiciones ocupadas.

Otro ejemplo importante para diferenciar StringBuffer y StringBuilder con String:


// En las siguientes lneas, vemos como StringBuffer y StringBuilder // pueden modificarse de manera intrnseca, sin necesidad de asignarlos // de nuevo a una variable StringBuffer stringBuffer = new StringBuffer("JOSE"); stringBuffer.append(" ANTONIO"); System.out.println("Valor de StringBuffer " + stringBuffer); StringBuilder stringBuilder = new StringBuilder("JOSE"); stringBuilder.append(" ANTONIO"); System.out.println("Valor de StringBuilder " + stringBuilder);

La salida en este caso es: Valor de StringBuffer JOSE ANTONIO Valor de StringBuilder JOSE ANTONIO

A MODO DE RESUMEN MUY RPIDO: -String no puede modificarse en s mismo, si no que necesita la reasignacin a una variable. -StringBuffer y StringBuilder permiten realizar modificaciones intrnsecas al objeto. -StringBuilder es ms rpido que StringBuffer, pues sus mtodos no son sincronizados. -En la mayora de los casos, es recomendable usar StringBuilder para el tratado de textos por temas de rendimiento.

2.1. File I/O.


2.1.1. Acceso a la entrada/salida estndar a travs de la clase System.
1) System.in: tiene los mtodos read para leer un byte de la entrada, y skyp, para saltar n bytes de la entrada. 2) System.out: implementa stdout como una instancia de la clase PrintStream, que puede utilizar los mtodos print() y println() con cualquier tipo bsico de Java como argumento. 3) System.err: implementa stderr de la misma forma que stdout. Como con system.out, se tiene acceso a los mtodos de PrintStream. Veamos el siguiente ejemplo: import java.io.*; class miType { public static void main( String args[] ) throws IOException { int c; int contador = 0; while( (c = System.in.read() ) != '\n' ) { contador++; System.out.print( (char)c ); } System.out.println(); // Lnea en blanco System.err.println( "Contados "+ contador +" bytes en total." ); } }

2.2. Acceso sobre ficheros


File: representacin abstracta de un fichero. FileReader: se utiliza para leer caracteres de un fichero, normalmente se envuelve dentro de BufferedReader. BufferedReader: clase usada para que facilitar y hacer ms eficiente el uso de FileReader, aadiendo adems el mtodo que permite leer lneas. FileWriter: anlogo a FileReader, permite escribir caracteres en un fichero. BufferedWriter: anlogo a BufferedReader, permite escribir caracteres en un fichero, de manera ms eficiente, aadiendo, adems de la posibilidad de escribir lneas.

Veamos el siguiente ejemplo:


package es.scjp.javahispano.tema6; import java.io.*; public class P622LeeFichero { public static void main(String[] arg) { File archivo = null; FileReader fr = null; BufferedReader br = null; try { // Apertura del fichero y creacion de BufferedReader para poder hacer una lectura comoda (disponer del metodo readLine()). archivo = new File("C:\\archivo.txt"); fr = new FileReader(archivo); br = new BufferedReader(fr); // Lectura del fichero String linea; while ((linea = br.readLine()) != null) System.out.println(linea); } catch (Exception e) { e.printStackTrace(); } finally { // En el finally cerramos el fichero, para asegurarnos // que se cierra tanto si todo va bien como si salta // una excepcion. try { if (null != fr) { fr.close(); } } catch (Exception e2) { e2.printStackTrace(); } } } }

2.3. Serializando utilizando el paquete java.io.


Serializar un objeto significa darle al mismo la posibilidad de persistir su estado en un fichero externo, y despus poder recuperarlo en el mismo estado.

As mismo, nos permite que, en un modelo de trabajo cliente servidor, nos permita poder que, una variable concreta de un cliente, pueda ser enviada al servidor y este tenga la capacidad de reproducir el estado inicial en el que se encontraba dicha variable. Para que una clase sea serializable, basta con que la misma implemente la interfaz del tipo Serializable. Debemos saber que para que una clase sea serializable todos los atributos de la misma, si son una clase (puesto que las variables comunes, int, long, etc... son serializables por s mismos al estar definidos como una secuencia de bits) deben ser serializables para que la clase padre o contenedora pueda ser serializable. Lo vemos en el siguiente ejemplo:
public class EjemploSerializable implements Serializable{ int a; int b; Hijo c; Aqu vemos que la clase EjemploSerializable tiene una referencia a un atributo c del tipo Hijo, que a su

vez tiene la siguiente definicin:


public class Hijo implements Serializable{ int a; int b; }

Tambin podemos hacer que haya atributos que no queden persistidos a la hora de serializar el objeto, de la siguiente manera:
public class Hijo implements Serializable{ transient int a; int b; }

Esto quiere decir que el atributo a es de tipo transient, lo que quiere decir que, a la hora de persistir el objeto, slo interesar almacenar el valor de la variable b. El serialVersionUID sirve para definir el nnero de versin de clase. Este identificador nos permite diferenciar el nmero de versin de clase y nos permitir discernir si el programa actual es capaz de leer instancias de clases persistidas anteriormente. Es probable que podamos serializar una clase, con una serie de atributos, y dejarla serializada, y ms tarde, modificar nuestro programa para aadir ms atributos. Veamos el siguiente ejemplo:
public class P623Serializable implements Serializable{ private static final long serialVersionUID = 1376790362021476502L; }

Al intentar recuperar una versin anterior, vemos que podemos tener problemas pues nuestra clase ha cambiado. Si hemos especificado el serialVersionUID el compilador detecta que hay un problema de compatibilidad de clases y podremos corregirlo, en caso contrario, tendremos un error muy desagradable, que es tener un error en el programa sin poder ser capaces de identificarlo, y, consecuentemente, corregirlo. Por otra parte, es bueno aadir que, si queremos serializar colecciones o arrays, todos sus elementos internos deben ser serializables.

2.4. Trabajando con fechas, nmeros y monedas: Calendar, dateFormat, date, locale, numberFormat
Date: la mayora de los mtodos estn obsoletos. Permite obtener la fecha actual, o bien la fecha a partir de un instante de tiempo especificado en milisegundos. Calendar: proporciona utilidades para hacer mn manejable el uso de fechas, dando mtodos que permiten calcular el da actual, la semana, el mes, la fecha, hacer operaciones de comparacin sobre la fecha, etc. Es una clase abstracta, adems, proporciona variables estticas. DateFormat: proporciona mtodos que permiten manejarse correctamente con el formato de fechas, y adaptarlo segn nuestros intereses. Locale: permite configurar formatos especficos de un idioma y/o registro, se puede aplicar, por ejemplo, a DateFormat.

Veamos el siguiente ejemplo: public static void main(String args[]) { //Obtenemos la fecha actual Date ahora = new Date(); //Obtenemos un calendario griego Calendar c = new GregorianCalendar(); //Asignamos la fecha actual a la actual c.setTime(ahora); //Obtenemos el primer dn de la semana System.out.println(c.getFirstDayOfWeek()); //Formateamos la fecha a formato corto System.out.println(DateFormat.getTimeInstance(DateFormat.SHORT).format( ahora)); //Formateamos la fecha a formato mediano System.out.println(DateFormat.getTimeInstance(DateFormat.MEDIUM) .format(ahora)); //Formateamos la fecha a formato largo System.out.println(DateFormat.getTimeInstance(DateFormat.LONG).format( ahora)); //Creamos un locale para Mnico, para posteriormente, formatearlo. Locale loc = new Locale("es","MX"); }

10

NumberFormat: permite formatear los nmeros correspondientes en Java. Los mtodos ms utilizados son: setMinimumIntegetDigits, setMinimumFractionDigits, setMaximumIntegerDigits y setMaximunFractionDigits.

package es.scjp.javahispano.tema6; import import import import import java.text.DateFormat; java.util.Calendar; java.util.Date; java.util.GregorianCalendar; java.util.Locale;

public class P624Fechas { public static void main(String args[]) { // Obtenemos la fecha actual Date ahora = new Date(); // Obtenemos un calendario griego Calendar c = new GregorianCalendar(); // Asignamos la fecha actual a la actual c.setTime(ahora); // Obtenemos el primer dn de la semana System.out.println(c.getFirstDayOfWeek()); // Formateamos la fecha a formato corto System.out.println(DateFormat.getTimeInstance(DateFormat.SHORT).format( ahora)); // Formateamos la fecha a formato mediano System.out.println(DateFormat.getTimeInstance(DateFormat.MEDIUM) .format(ahora)); // Formateamos la fecha a formato largo System.out.println(DateFormat.getTimeInstance(DateFormat.LONG).format( ahora)); } }

La salida es la siguiente: 2 18:46 18:46:39 18:46:39 CEST

2.5. Expresiones regulares.


Java proporciona los siguientes mtodos para la definicin de patrones de bsqueda:

11

Pattern.compile: permite compilar un patrn de bsqueda. Match: permite aplicar el patrn de bsqueda a un string concreto.

Un ejemplo de uso puede ser el siguiente:


package es.scjp.javahispano.tema6; import java.util.regex.Pattern; public class P65ExpresionesRegulares { /** * @param args */ public static void main(String[] args) { // Create a pattern to match breaks Pattern p = Pattern.compile("[,\\s]+"); // Split input with the pattern String[] result = p.split("one,two, three four , five"); for (int i = 0; i < result.length; i++) System.out.println(result[i]); } }

La salida es la siguiente: one two three four five

12

You might also like