jueves, 28 de agosto de 2014

Métodos básicos de la clase String

La clase String se encuentra en java.lang, paquete que viene precargado en Java.

Un String en Java representa una cadena de caracteres no modificable. Esto quiere decir que para combinar 2 de su tipo, Java crea un tercero con la suma de las 2 dimensiones y después agrega el primer String  y luego el otro.

A todo tipo de dato que se le agregue comillas dobles se implementan como objetos de la clase String.

En esta entrada se verán varios métodos, siendo una entrada al blog algo extensa pero que contiene información valiosa para el programador.

*La mayoría de los métodos usados si no son manejados correctamente arrojan excepciones.

Métodos

------------------------------------------------------------------------------------------------------------------

     - charAt(int índice).

Método que recibe un número entero, el cual es el número del carácter que se desea obtener.
*Indexado en 0 [cero].

String prueba = “Hola”;

prueba.charAt(0) = Retorna el carácter  [ H ].
prueba.charAt(2) = Retorna el carácter  [ l ].

------------------------------------------------------------------------------------------------------------------

     - codePointAt(int índice).

Recibe un número entero el cual es el número del carácter que se desea obtener y retorna el valor del carácter en ASCII.

String prueba = “Hola”;

Ejemplo 1: 

codePointAt (0) = Retorna el número 72 que en la tabla ASCII es el carácter  [H].

Ejemplo 2: 

codePointAt (2) = Retorna el número 111 que en la tabla ASCII es el carácter  [o].

------------------------------------------------------------------------------------------------------------------

     - codePointBefore (int índice).

Devuelve el valor del carácter en ASCII antes de que el índice especificado.

String prueba = “Hola”;

Ejemplo :

codePointBefore (1) = Retorna el número 72 que en la tabla ASCII es el carácter  [H].

------------------------------------------------------------------------------------------------------------------
- compareTo(String cadena):

Permite comparar dos cadenas de caracteres. Distingue mayúsculas y minúsculas.

Retorna un valor entero.

+ Si el valor es cero (0), las dos cadenas son iguales.
+ Si el valor es entero positivo, el String que invoca es mayor.
+ Si el valor es entero negativo, el String que invoca es menor.

(string_invoca).compareTo(string_invocado)

Ejemplo 1:

String cadena1 = "Hola Mundo";
String cadena2 = cadena1;

int resultado = cadena1.compareTo(cadena2);

resultado = 0;

Ejemplo 2:

String cadena1 = “Hola Mundo”;
String cadena2 = “hola mundo”;

cadena1.compareTo(cadena2);

int resultado = cadena1.compareTo(cadena2);

resultado = 1.
------------------------------------------------------------------------------------------------------------------

- compareToIgnoreCase(String cadena):

Al igual que la anterior, pero no tiene en cuenta mayúsculas o minúsculas. Retorna lo mismo que el método anterior.

Ejemplo:

String cadena1 = “Hola Mundo”;
String cadena2 = “hola mundo”;

cadena1.compareTo(cadena2);

int resultado = cadena1.compareTo(cadena2);

resultado = 0.
------------------------------------------------------------------------------------------------------------------

- equals(String cadena):

Sirve para comparar dos cadenas, compara el contenido de los objetos.

Retorna booleano true – false.

El resultado tiene en cuenta si la cadena esta en mayúsculas-minúsculas e inclusive los espacios para retornar el veredicto. *El programador tiene que tener en cuenta esto.


string1.equals(string2);

Ejemplo:

String cadena1 = “Hola Mundo”;
String cadena2 = “hola mundo”;

boolean  respuesta = cadena1.equals(cadena2);

respuesta = false;
------------------------------------------------------------------------------------------------------------------

- equalsIgnoreCase(String cadena):

Sirve para comparar dos cadenas, pero no tiene en cuenta mayúscula o minúscula.

Retorna booleano true – false.

String cadena1 = “Hola Mundo”;
String cadena2 = “hola mundo”;

boolean  respuesta = cadena1.equals(cadena2);
respuesta = true;
------------------------------------------------------------------------------------------------------------------

- indexOf(String cadena):

Busca un carácter o un grupo de caracteres en una cadena en una posición inicial.

Retorna el índice donde comienza el carácter-grupo de caracteres en la cadena.
Retorna -1 si no se encuentra la cadena solicitada en el String.

String cadena1 = "Hola Mundo";
String buscar = "Mun";
       
int resultado = cadena1.indexOf(buscar);

resultado = 5;
------------------------------------------------------------------------------------------------------------------

- indexOf(char letra):

Busca un carácter en una cadena en una posición inicial.

Retorna el índice donde comienza el carácter en la cadena.
Retorna -1 si no se encuentra el carácter solicitado en el String.

String cadena1 = "Hola Mundo";
char letraBuscar = 'n';

int resultado = cadena1.indexOf(letraBuscar);

resultado = 7 ;
------------------------------------------------------------------------------------------------------------------

- indexOf( String cadena , int índice):

Busca un carácter o un grupo de caracteres en una cadena en una posición inicial.

+ Mandando el String que se va a buscar y un entero, se tomara al entero como un índice, donde comenzara la búsqueda del String.

Retorna el índice donde comienza el carácter-grupo de caracteres en la cadena.
Retorna -1 si no se encuentra la cadena solicitada en el String.

String cadena1 = "Hola Mundo";
String letraBuscar = "un";
int indice = 3;

int resultado = cadena1.indexOf(letraBuscar,indice);
resultado = 6 ;
------------------------------------------------------------------------------------------------------------------

- indexOf( char letra , int índice):

Busca un carácter en una cadena en una posición inicial.

+ Mandando el char que se va a buscar y un entero, se tomara al segundo entero como un índice, donde comenzara la búsqueda del carácter.

Retorna el índice donde comienza el carácter en la cadena.
Retorna -1 si no se encuentra el carácter solicitado en el String.

String cadena1 = "Hola Mundo";
String letraBuscar = "un";
int indice = 3;

int resultado = cadena1.indexOf(letraBuscar,indice);
resultado = ;
------------------------------------------------------------------------------------------------------------------

- lastIndexOf(String cadena):

Busca un carácter o un grupo de caracteres en una cadena en una posición final.

Retorna el último índice donde comienza el carácter-grupo de caracteres en la cadena.
Retorna -1 si no se encuentra la cadena solicitada en el String.

String cadena1 = "Hola Mundo";
String buscar = "Mun";
       
int resultado = cadena1.indexOf(buscar);

resultado = 5;
------------------------------------------------------------------------------------------------------------------

- lastIndexOf(char letra):

Busca un carácter en una cadena en una posición final.

Retorna el último índice donde comienza el carácter en la cadena.
Retorna -1 si no se encuentra la cadena solicitada en el String.

String cadena1 = "Hola Mundo";
char buscar = ‘o’;
       
int resultado = cadena1.indexOf(buscar);

resultado = 9;
------------------------------------------------------------------------------------------------------------------

- lastIndexOf ( String cadena , int índice):

Busca un carácter o un grupo de caracteres en una cadena en una posición final.

+ Mandando el String que se va a buscar y un entero, se tomara al entero como un índice buscando hacia atrás, empezando en el índice especificado.

Retorna el último índice donde comienza el carácter-grupo de caracteres en la cadena.
Retorna -1 si no se encuentra la cadena solicitada en el String.

String cadena1 = "Hola Mundo";
String letraBuscar = "un";
int indice = 3;

int resultado = cadena1.indexOf(letraBuscar,indice);
resultado = 6 ;
------------------------------------------------------------------------------------------------------------------

- lastIndexOf ( char letra , int índice):

Busca un carácter en una cadena en una posición final.

+ Mandando el char que se va a buscar y un entero, se tomara al segundo entero como un índice buscando hacia atrás, empezando en el índice especificado.

Retorna el último índice donde comienza el carácter en la cadena.
Retorna -1 si no se encuentra el carácter solicitado en el String.

String cadena1 = "Hola Mundo";
char letraBuscar = ‘o’;
int indice = 3;

int resultado = cadena1.indexOf(letraBuscar,indice);
resultado = 9 ;
------------------------------------------------------------------------------------------------------------------

- length():

Retorna la longitud de una cadena, un número que es el número total de caracteres que contiene la cadena.

String cadena=”Hola Mundo”

int longitud =cadena.length();

longitud =10.
------------------------------------------------------------------------------------------------------------------

- matches(String regex):

Retorna true false si la cadena coincide con la expresión regular recibida.

String cadena=”1234543AB”;
String regex = “[0-9]+”;

boolean resultado = cadena.matches(regex);

resultado = false;
------------------------------------------------------------------------------------------------------------------

- replace( String cadena1 , String cadena2):

Reemplaza un carácter por otro carácter en una cadena. Puede aplicarse para remplazar una cadena por otra.

Retorna un nuevo String con las modificaciones correspondientes.

String cadena = "Hola Mundo";
String letraQuitar = "o";
String letraNueva = "a";

String cadena2 = cadena.replace(letraQuitar, letraNueva);

cadena2 = Hala Munda;
------------------------------------------------------------------------------------------------------------------

- replaceAll (String regex , String cadena2):

Reemplaza cada subcadena de esta cadena que coincide con la expresión regular dada con el reemplazo dado.

Retorna un nuevo String con las modificaciones correspondientes.

String cadena = "Hola Mundo Mundo Mundo";
String cadenaQuitar = "Mundo";
String cadenaNueva = "";

String cadena2 = cadena.replaceAll(cadenaQuitar, cadenaNueva);

cadena2 : Hola___ ;

*Los _ se ocupa para representar los espacios que se dejo cuando se remplazo la cadena. Se tiene que tener en cuenta eso a la hora de remplazar las cosas.

------------------------------------------------------------------------------------------------------------------

- substring( int índice):

Retorna una nueva cadena a partir de otra cadena.

+ Mandando como parámetro solamente un entero, el entero se toma como un índice y retorna desde el índice hasta el final de la cadena.

String cadena = "Hola_Mundo";
int index = 4;

String resultado = cadena.substring(index);

resultado = _Mundo;
------------------------------------------------------------------------------------------------------------------

- substring ( int índice1 , int índice2):

Retorna una nueva cadena a partir de otra cadena.

+ Mandando como parámetro 2 enteros, se retorna una cadena tomando como índice el primer entero hasta el segundo entero enviado.

String cadena = "Hola_Mundo";
int index = 4;
int endIndex = 9;

String resultado = cadena.substring(index, endIndex);

resultado = _Mund;
------------------------------------------------------------------------------------------------------------------

- toCharArray():

Convierte una cadena de caracteres en un arreglo tipo char.

Retorna arreglo de caracteres.

String cadena = "Hola_Mundo";

char [ ] resultado = cadena.toCharArray();

resultado = [H, o, l, a, _, M, u, n, d, o];

------------------------------------------------------------------------------------------------------------------

- startsWith( String cadena):

Busca si una cadena inicia con una cadena especifica.

Retorna true false.
Tener cuidado por que distingue entre mayúsculas y minúsculas.

+ Al recibir una cadena busca si en la cadena que se invoca se encuentra la cadena recibida.

String cadena1 = "Hola Mundo";
String iniciar = "H";

boolean resultado = cadena1.startsWith(iniciar);

resultado = true;
------------------------------------------------------------------------------------------------------------------

- startsWith( String cadena , int índice):

Busca si una cadena inicia con una cadena especifica.

Retorna true false.
Tener cuidado por que distingue entre mayúsculas y minúsculas.

+ Al recibir una cadena y un entero, busca si en la cadena se encuentra la cadena recibida desde el entero recibido que se toma como un índice.

String cadena1 = "Hola Mundo";
String iniciar = "u";
int index = 6;

boolean resultado = cadena1.startsWith(iniciar, index);

resultado = true;
------------------------------------------------------------------------------------------------------------------

- endsWith( String cadena) :

Busca si una cadena termina con una cadena especifica.
Retorna true false.
Tener cuidado, distingue entre mayúsculas y minúsculas.

String cadena1 = "Hola Mundo";
String iniciar = "o";

boolean resultado = cadena1.endsWith(iniciar);

resultado = true;
------------------------------------------------------------------------------------------------------------------

           - toLowerCase(): 

Convierte una cadena a minúsculas.

Retorna un String con las modificaciones correspondientes.

String cadena1 = "Hola Mundo";

String resultado = cadena1.toLowerCase();

resultado = hola mundo;

------------------------------------------------------------------------------------------------------------------

          - toUpperCase ():

Convierte una cadena a Mayúsculas.

Retorna un String con las modificaciones correspondientes.

String cadena1 = "Hola Mundo";

String resultado = cadena1.toUpperCase();

resultado = HOLA MUNDO;
------------------------------------------------------------------------------------------------------------------

          - trim():

Retorna un String con los espacios finales e iniciales eliminados.

String cadena1 = "      Hola Mundo      ";

String resultado = cadena1.trim();

resultado = “Hola Mundo”;
------------------------------------------------------------------------------------------------------------------

Con esto finaliza los métodos básicos de la clase String, teniendo en cuenta que son de gran ayuda para el programador en diferentes situaciones.

Para mayor información consulten la página oficial de Oracle, en el siguiente link: Clase String

Por su atención Muchas Gracias. 

Estoy a su disposición para cualquier duda o aclaración.

domingo, 20 de julio de 2014

BufferedReader vs Scanner


En el lenguaje java hemos visto dos de las clases más usadas para lectura que son el BufferedReader y el Scanner. En resumen sabemos que el Scanner trabaja con tokens que son cadenas de caracteres que se separan mediante delimitadores que por defecto el Scanner tiene el espacio y que el BufferedReader trabaja manualmente carácter por carácter. Usted como programador seguramente las has usado alguna vez y se ha preguntado:

¿Cuál es más fácil de usar?


Para saber esto hemos elaborado el siguiente ejemplo:
Se requiere leer los siguientes valores en una sola línea, como se muestran abajo.

hola 12345 12.22

Se deberán guardar los valores en variables de tipo de dato String, int y float, a continuación se brindaran algunas soluciones para poder resolver el anterior ejemplo.

Solución sencilla con Scanner:

Código:
import java.util.Scanner;
/**
 *
 * @author Luis
 */
public class Solucion1Scanner {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String caracteres = sc.next(); //Lectura con Scanner
        int entero = sc.nextInt();
        float enteroFlotante = sc.nextFloat();
        System.out.println("Palabra " + caracteres);
        System.out.println("Numero " + entero);
        System.out.println("Flotante " + enteroFlotante);
    }
}
Podemos observar que los métodos que tiene Scanner nos pueden apoyar en cuestión de lecturas con cualquier tipo de dato primitivo (exepto: el char), pero con el BufferedReader tenemos que arreglárnoslas para poder tener cualquier tipo de dato, aquí se brindaran dos tipos de soluciones.

Solución sencilla con BufferedReader :

Código:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
 *
 * @author Luis
 */
public class Solucion1BufferedReader {
    public static void main(String[] args) throws IOException{
        InputStreamReader flujoEntrada = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(flujoEntrada);
        String[] arreglo = br.readLine().split(" ");
        //el metodo split Divide los strings conforme a los espacios
        String caracteres = arreglo[0];
        int entero = Integer.parseInt(arreglo[1]);
        float enteroFlotante = Float.parseFloat(arreglo[2]);
        System.out.println("Palabra " + caracteres);
        System.out.println("Numero " + entero);
        System.out.println("Flotante " + enteroFlotante);
    }
}

Solución compleja con BufferedReader:

Codigo:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Pattern;
/**
 *
 * @author Luis
 */
public class Solucion2BufferedReader {
    public static void main(String[] args) {
        InputStreamReader flujoEntrada = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(flujoEntrada);
        try {
            String linea = br.readLine(); 
            String[] arregloStrings = linea.split(" "); 
            int numero = 0;
            String palabra = "";
            float numeroFlotante = 0;
            for (int i = 0; i < arregloStrings.length; i++) { //Recorremos nuestro arreglo de strings
                String expresionRegular = "[a-z]+";
                boolean bandera = Pattern.matches(expresionRegular, arregloStrings[i]);
                //El metodo matches retornara true si el string corresponde al expresion
                if (bandera == true) { 
                    palabra = arregloStrings[i]; //
                }
                expresionRegular = "[0-9]+";
                bandera = Pattern.matches(expresionRegular, arregloStrings[i]);
                if (bandera == true) {
                    numero = Integer.parseInt(arregloStrings[i]);
                }
                expresionRegular = "^[0-9]*[.][0-9]+$";
                bandera = Pattern.matches(expresionRegular, arregloStrings[i]);
                if (bandera == true) {
                    numeroFlotante = Float.parseFloat(arregloStrings[i]);
                }
            }
            System.out.println("Palabra " + numero);
            System.out.println("Numero " + palabra);
            System.out.println("Flotante " + numeroFlotante);
        } catch (IOException e) {
            System.out.println("Error");
        }
    }
}
Resultado del ejemplo anterior


Estas soluciones que fueron aplicadas al BufferedReader también podrán ser aplicadas con el Scanner, usted podrá elaborarlas sin problemas.
Quedo claro que en cuestión de comodidad el Scanner es amplio vencedor sobre el BufferedReader, ya que este nos hace trabajar con caracteres.

¿Cuál hace menor tiempo?


Ahora veremos quién es el mejor en tiempo con las siguientes pruebas que hemos realizado:
Primero elaboraremos un archivo de texto que será nuestra lectura por Scanner y BufferedReader, con el mismo numero de líneas y contenido de texto.

Codigo
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
/**
 *
 * @author Luis
 */
public class CrearArchivoPrueba {
    public static void main(String[] args) {
        InputStreamReader flujoEntrada = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(flujoEntrada);
        System.out.println("**Crear archivo de texto**\n" + "Ruta del archivo:");
        try {
            String ruta = br.readLine(); 
            System.out.println("Nombre del archivo:");
            String nombre = br.readLine();
            System.out.println("Texto:");
            String texto = br.readLine();
            System.out.println("Numero de lineas:");
            int numero = Integer.parseInt(br.readLine());
            System.out.println("Se ha finalizado");
            crearArchivo(ruta, nombre, texto, numero);
        } catch (IOException e) {
            System.out.println("Error");
        }
    }
    
    public static void crearArchivo(String ruta, String nombreDelArchivo,
            String texto, int numeroLineas) throws IOException {
        
        ArrayList lineas = new ArrayList<>();
        for (int i = 0; i < numeroLineas; i++) { //Numero de lineas que seran agregadas al arraylist
            lineas.add(texto);
        }
        File archivo = new File(ruta + "\\" + nombreDelArchivo); 
        /*La clase File nos permite crear un archivo de tipo txt,
        en el constructor le agregamos el directorio donde queremos crear el archivo*/
        FileWriter archivoEscritura = new FileWriter(archivo, true);  
        //La clase FileWriter hace que podamos escribir caracteres dentro del archivo
        BufferedWriter bw = new BufferedWriter(archivoEscritura);
        //BufferedWriter permite crear un flujo de caracteres de salida
        for (int i = 0; i < lineas.size(); i++) {
            String linea = lineas.get(i);
            bw.write(linea); 
            bw.newLine(); //Salto de linea
        }
        bw.close(); // Cierra el flujo
    }
}
//

Ingresamos los datos como en el siguiente ejemplo:
Archivo de texto PruebaLineas.txt


Este archivo de texto será para realizar pruebas para nuestro métodos de lectura para toda la línea que tiene BufferedReader con readLine() y Scanner con nextLine().


Archivo de texto PruebaNext.txt


También este archivo se usara para pruebas con los métodos de Scanner next() y BufferedReader nextManual() “este método no lo tiene el BufferedReader por defecto”.
Bueno, para ver los resultados de las pruebas de BufferedReader y Scanner usaremos el siguiente código:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
/**
 *
 * @author Luis
 */
public class Pruebas {
    public static void main(String[] args) {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("**Pruebas de BufferredRead y Scanner**\n" + "Metodos de BufferedReader:\n"
                + "a)readLine " + "b)nextManual\n" + "Metodos de Scanner:\n" + "c)nextLine " + "d)next");
        try {
            char letra = (char) br.read();
            long tInicial = System.currentTimeMillis(); // Para Medir el tiempo inicial
            switch (letra) {
                case 'a':
                    pruebaReadLine("PruebaLineas.txt"); //En el constructor ponemos el nombre de nuestro txt realizado                
                    break;
                case 'b':
                    pruebaNextManual("PruebaNext.txt");
                    break;
                case 'c':
                    nextLine("PruebaLineas.txt");
                    break;
                case 'd':
                    next("PruebaNext.txt");
                    break;
                default:
                    System.out.println("Caracter incorrecto");
                    break;
            }
            long tFinal = System.currentTimeMillis() - tInicial;
            double promedio = (double) tFinal / 1000000;
            /*Realizamos la operacion de forma directa para evitar que se tome 
             mas tiempo de esto con un contador*/
            System.out.printf("%.7f", promedio);
        } catch (IOException e) {
            System.out.println("Error " + e);
        }
    }

    public static void pruebaReadLine(String nombreArchivo) throws IOException {
        BufferedReader brFileReader = new BufferedReader(new FileReader(nombreArchivo));
        //La clase FileReader hace que podamos leer caracteres dentro del archivo        
        while (brFileReader.ready()) { //Mientras que el buffer no este vacio 
            String linea = brFileReader.readLine();
        }
        brFileReader.close();  // Se cierra el flujo
    }

    public static void pruebaNextManual(String nombreArchivo) throws IOException {
        BufferedReader brFileReader = new BufferedReader(new FileReader(nombreArchivo));
        while (brFileReader.ready()) {
            char caracter = '/'; //Se inicializa el char
            String palabra = ""; //Se incializa el string 
            while (true) {
                caracter = (char) brFileReader.read(); //Lee un caracter
                palabra += caracter;
                if (caracter == '\n' || caracter == ' ') { 
                  // Si es salto de linea o esta vacio se rompe el ciclo
                    break;
                }
            }
        }
        brFileReader.close();
    }

    public static void next(String nombreDelArchivo) throws IOException {
        Scanner scFile = new Scanner(new FileReader(nombreDelArchivo));
        while (scFile.hasNext()) { //Mientras tenga caracteres
            String palabra = scFile.next();
        }
    }

    public static void nextLine(String nombreDelArchivo) throws IOException {
        Scanner scFile = new Scanner(new FileReader(nombreDelArchivo));
        while (scFile.hasNextLine()) { //Mientras tenga una linea
            String linea = scFile.nextLine();
        }
    }
}

Metodos
Tiempo en milisegundos
readLine()
0.0005620
nextManual()
0.0006850
nextLine()
0.0025680
next()
0.0015290
                      Tabla de resultados

Como se pudo observar el ganador en esta prueba fue el uso de la clase BufferedReader respecto a los métodos utilizados, podemos decir que si queremos elaborar un código optimo con mejor tiempo recomendamos usar esta clase.

¿Cuál es mejor?


Elegir una ganadora es muy complicado porque cada una tiene sus propias ventajas unas sobre otras, el programador deberá saber que es lo más conveniente para utilizar en su código por ejemplo si se quiere trabajar con una lectura de línea de forma manual para realizar trabajos sencillos se podrá utilizar el BufferedReader o bien queremos usar una manera más automatizada se usara el Scanner, usted tendrá la decisión de escoger la que crea más conveniente para su caso.