Professional Documents
Culture Documents
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.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.
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.
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.
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
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)); } }
11
Pattern.compile: permite compilar un patrn de bsqueda. Match: permite aplicar el patrn de bsqueda a un string concreto.
12