Android

Android


ELEMENTOS DE JAVA

Página 20 de 25

         miArray3[1][0]=10;

         miArray3[1][1]=11;

         miArray3[2][0]=20;

         miArray3[2][1]=21;

         miArray3[2][2]=22;

         tv.append("\n\n miArray3:");

         for (int i=0;i<3;i++){

         tv.append("\n Fila: ");

          for(int j=0;j<=i;j++){

             tv.append(""+miArray3[i][j]+" , ");

          }

         }

         double[][] miArray4={ {1,2},{3,4,5},{6},{7,8,9,0} };

         tv.append("\n\n miArray4: ");

         filas=miArray4.length;

         for (int i=0;i<filas;i++){

         columnas=miArray4[i].length;

         tv.append("\n Fila:");

         for(int j=0;j<columnas;j++){

            tv.append(" "+miArray4[i][j]+" , ");

         }

      }

    }

 }

A.16. Cadenas

La clase String está definida en el paquete java.lang y representa cadenas de caracteres. Una cadena o String es un objeto de esta clase. Una String literal es un texto rodeado por comillas dobles. Para crear un objeto String se puede usar el constructor de la clase o usar una cadena literal, por ejemplo:

   String cadena;

   cadena = new String("esto es una cadena");

   cadena = "esto es una cadena";

Para transformar a String una variable numérica, booleana o carácter, se usa el método estático valueOf().

   double x=1.245;

   String cadena= String.valueOf(x);

Para concatenar cadenas se usa el operador "+".

   String cadena1= "esto es ";

   String cadena2= "una cadena";

   String cadena3= cadena1+cadena2;

El operador "+" también realiza la conversión a cadenas de otros tipos de datos.

   double x=1.256;

   String cadena1= "x="+x;

Este hecho lo hemos utilizado repetidamente en todos los ejemplos anteriores, pues el argumento de append() es una String.

Java incluye numerosos métodos para manipular cadenas incluyendo:

•   length(). La longitud de una cadena cadena1 se extrae mediante cadena1.length().

•   substring(int ini,int fin). Método para extraer una subcadena. Se especifica la posición del primer caracter incluido y del primer caracter no incluido. La posición del primer caracter tiene el índice cero.

•   toUpperCase() y toLowerCase(). Conversión a mayúsculas y a minúsculas.

•   compareTo(String cadena). Compara con otra cadena y devuelve un entero negativo si la primera es menor que la segunda, y positivo si ocurre lo contrario. Si son iguales devuelve cero.

•   indexOf(string cadena).   Devuelve   la   posición   de   la   primera ocurrencia de una subcadena.

•   replace(char a, char b). Reemplaza el primer caracter por el segundo.

•   trim(). Elimina espacios en blanco al principio y al final.

•   toCharArray(). Extrae los caracteres de una cadena en un array.

El uso de estos métodos se ilustra en el siguiente programa. La salida se puede ver en la figura A.21..

  public class EjemploJava1 extends Activity {

    TextView tv;    

     @Override

     public void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);

         setContentView(R.layout.main);

         tv= (TextView) findViewById(R.id.textView);

         String cadena1="Cadenas de caracteres";

         tv.setText(cadena1);

         // constructor

         String cadena2=new String("\n Constructor de cadenas");

         tv.append(cadena2);

         // Concatenacion

         cadena1="\n Concatenacion";

         cadena2=" de cadenas \n";

         String cadena3=cadena1+cadena2;

         tv.append(cadena3);

         // Transformacion a cadena con valueOf()

         double x=3.1416e-3;

         cadena2 = String.valueOf(x);

         tv.append("Transformacion de double a cadena\n");

         tv.append(cadena2);

         // conversion de String a double

         cadena1="3.1416e-3";

         x = Double.parseDouble(cadena1);

         x= x*2;

         tv.append("\n Conversion de string a double\n "+x);

         // conversion de String a int

         cadena1="1234";

         int i= Integer.parseInt(cadena1);

         i=i*2;

         tv.append("\n Conversion de string a int\n "+i);

         // longitud de una cadena

         cadena1="Granada";

         int longitud= cadena1.length();

         tv.append("\n La longitud de Granada es "+longitud);

         longitud="Nueva York".length();

         tv.append(

              "\n La longitud de Nueva York es "+longitud);

         // conversion a mayusculas y minusculas

         cadena1="Conversion a mayusculas";

         cadena1=cadena1.toUpperCase();

         tv.append("\n"+cadena1);

         cadena1="CONVERSION A MINUSCULAS";

         cadena1=cadena1.toLowerCase();

         tv.append("\n"+cadena1);

         // subcadenas. Indices comienzan en cero

         cadena1="Extrayendo subcadenas";

         // desde el principio hasta el caracter decimo

         cadena2=cadena1.substring(0,10);

         // desde el 11 hasta el final

         cadena3=cadena1.substring(11);

         tv.append("\n"+cadena2);

         tv.append("\n"+cadena3);

         // comparacion de cadenas

         cadena1="Granada";

         cadena2="Albacete";

         i=cadena1.compareTo(cadena2);

         if( i<1){

          tv.append("\n"+cadena1+" antes que "+cadena2);

          }

         else{

          tv.append("\n"+cadena1+" despues que "+cadena2);

          }

         // búsqueda de subcadenas

         cadena1="Granada";

         i=cadena1.indexOf("da");

         tv.append("\n Granada contiene da en la posicion "+i);

         // reemplazar caracteres

         cadena1="Granada";

         cadena2=cadena1.replace(‘a’,’u’);

         tv.append(

             "\n Reemplazando las aes por ues: "+cadena2);

         //elimina espacios en blanco

         cadena1=

            "    trim elimina blancos  al inicio y fin     ";

         cadena1=cadena1.trim();

         tv.append("\n*"+cadena1+"*");

         // extraccion de los caracteres

         cadena1="Granada";

         char[] letras=cadena1.toCharArray();

         tv.append("\n Separando los caracteres:\n");

         for (int j=0;j<letras.length;j++){

          tv.append(" + "+letras[j]);

         }

     }

 }

Figura A.21. Manipulación de cadenas.

A.17. Formato numérico

Java posee una completa librería para manipular cadenas. En esta sección introducimos la clase DecimalFormat para dar formato a números decimales, transformándolos en cadenas. Esta clase es de utilidad para mostrar números en pantalla con una estructura de cifras determinada, o para escribirlos en un fichero. Para ello, primero se construye un objeto de tipo DecimalFormat:

DecimalFormat df = new DecimalFormat(patron)

donde patron es una cadena indicando el número de cifras deseado, o formato. Luego se emplea el método format() para transformar un número en una cadena con dicho formato. Por ejemplo:

   double x=1.2345;

   String cadena = df.format(x);

El número se redondea hacia arriba. Las principales reglas para especificar el patrón son las siguientes:

•   Un punto indica la posición del punto decimal.

•   El símbolo 0 indica un dígito o un cero si no hay ningún dígito en esa posición. Por ejemplo, el patrón "00.000" indica números con tres decimales y con dos cifras como mínimo a la izquierda del punto decimal, por ejemplo, 12.345, 01.234, 12.340, 123.450.

•   El símbolo # indica un dígito. Si no hay ningún dígito en esa posición, no escribe nada. Por ejemplo, el patrón "##.###" produce números con el formato 12.345, 1.23, 123.45.

•   El símbolo E seguido de ceros se utiliza para notación científica e indica una potencia de 10. Por ejemplo, el patrón "0.00E00" produciría los números 1.23E03, 0.12E10, 1.20E-01.

•   Una coma indica agrupación de cifras con un separador, Por ejemplo, el patron ",000" agrupa por miles, como en 12,000.

•   Con un punto y coma se puede especificar un símbolo alternativo al signo menos de los números negativos, en lugar de un guión.

Por defecto se utiliza la notación "local" que generalmente consiste en que el punto decimal es una coma y el separador de cifras es un punto. Para modificar el separador es necesario especificar un objeto DecimalFormatSymbols, que define los separadores, al definir el formato. Por ejemplo, para que el punto decimal se escriba siempre con un punto:

DecimalFormatSymbols symbols= new

                            DecimalFormatSymbols(Locale.US);

symbols.setDecimalSeparator(‘.’);

df= new DecimalFormat(".###",symbols);  

El objeto symbols lleva los símbolos locales de Estados Unidos, pero hemos modificado su separador decimal con setDecimalSeparator().

En el siguiente programa mostramos varios ejemplos de formato. El resultado se puede ver en la figura A.22..

  import java.text.DecimalFormat;

  import java.text.DecimalFormatSymbols;

  import java.util.Locale;

  import android.app.Activity;

  import android.os.Bundle;

  import android.widget.TextView;

  public class EjemploJava1 extends Activity {

    TextView tv;

     @Override

     public void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);

         setContentView(R.layout.main);

         tv= (TextView) findViewById(R.id.textView);

         tv.setText("DecimalFormat");

         double x,y,z;

         x=12345.6789;

         tv.append("\n Sin formato x="+x);

         DecimalFormat df1;

         df1= new DecimalFormat(".#");

         tv.append("\n Una cifra decimal: "+df1.format(x));

         df1= new DecimalFormat(".##");

         tv.append("\n Dos cifras decimales: "+df1.format(x));

         df1= new DecimalFormat(".###");

         tv.append(

              "\n Tres cifras decimales: "+df1.format(x));

         df1= new DecimalFormat(",###.##");

         tv.append("\n Agrupar por miles: "+df1.format(x));

         DecimalFormatSymbols symbols =

                 new DecimalFormatSymbols(Locale.US);

         symbols.setDecimalSeparator(‘.’);

         df1= new DecimalFormat(".###",symbols);

         tv.append("\n\n Punto decimal = ."+df1.format(x));

         y=1.234;

         z=-1.234;

         tv.append(

           "\n\n Rellenar con ceros a derecha e izquierda:");

         tv.append("\n sin formato y="+y);

         tv.append("\n sin formato z="+z);

         // El ; permite definir el simbolo del signo menos

         df1= new DecimalFormat("00.0000;menos",symbols);

         tv.append("\n "+df1.format(y));

         tv.append("\n "+df1.format(z));

         tv.append("\n\n Notación científica");

         df1= new DecimalFormat("0E0",symbols);

         tv.append("\n "+df1.format(y));

         df1= new DecimalFormat("0.0E00",symbols);

         tv.append("\n "+df1.format(y));

         df1= new DecimalFormat("00.00##E00",symbols);

         tv.append("\n "+df1.format(y));

         df1= new DecimalFormat(".00E0",symbols);

         tv.append("\n "+df1.format(y));

     }

 }

Figura A.22. Uso de la clase DecimalFormat para dar formato a los números.

A.18. Manejo de Excepciones

Cuando en la ejecución de un programa se produce un error, ésta se detiene. Cada error suele producir un mensaje o excepción, que permite determinar el problema. Con el manejo de excepciones podemos evitar errores y que el programa siga ejecutándose. Para manejar una excepción se usa un bloque try-catch. El código donde se puede producir un error debe estar en el bloque try. Si el error se produce, se lanza una excepción y se ejecuta el código del bloque catch, que es el que recoge la excepcion. Opcionalmente se puede incluir un bloque finally, que se ejecuta en todo caso, se produzca la excepción o no.

   try {

   // codigo que arroja la excepcion

   }

   catch (Exception e){

   // codigo que recoge la excepcion

   }

   finally {

   // codigo que se ejecuta siempre

   }

La instrucción catch requiere un parámetro e, que es un objeto de tipo  Exception o una de sus subclases, que lleva la información del tipo de error producido. En el siguiente programa demostramos el manejo de excepciones forzando dos errores típicos: intentar acceder a índices de un array que no existen, lo que arroja una excepción del tipo ArrayIndexOutOfBoundException, y acceder a índices de una cadena que tampoco existen, lo que arroja una excepción de tipo StringIndexOutOfBoundException. El tipo de excepción recogido se escribe en pantalla, ver figura A.23..

  public class EjemploJava1 extends Activity {

    TextView tv;

     @Override

     public void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);

         setContentView(R.layout.main);

         tv= (TextView) findViewById(R.id.textView);

         tv.setText("Excepciones\n");

         double[] v =new double[10];

         double x=-1;

         try {

          x=v[10];

         } catch(Exception e){

          tv.append("\n\n Excepcion encontrada: "+e);

          tv.append(

                "\n\n Se ha intentado acceder al indice 10 "

                +"del array v[10]");

         } finally{

          tv.append("\n x="+x);

         }

         String cadena="abcdefg";

         try{

          tv.append("\n"+cadena.substring(15,20));

         } catch(Exception e){

         tv.append("\n\n Excepción encontrada: "+e);

         tv.append("\n\n Se ha intentado acceder " +

                "a la posicion 15 de  "+cadena);

         }

     }

  }

Figura A.23. Uso de bloques try-catch para recoger excepciones.

Finalmente, indiquemos que un método puede arrojar una excepción y ésta ser declarada mediante la etiqueta throws, por ejemplo:

   public metodo throws Excepcion {

      ...

      throw e;

   }

En el caso en que se produzca la excepción, el método debe arrojarla mediante la instrucción throw e.

A.19. Interfaces

En Java un método no puede ser el argumento de otro método. Por ejemplo, si escribimos un método para calcular el mínimo de una función F(x), el nombre de la función debe conocerse de antemano. Si queremos minimizar varias funciones distintas, esto podría ser un problema. Las interfaces resuelven este problema, definiendo métodos vacíos, que se pueden implementar posteriormente por distintas clases. Así una clase podría contener la función a minimizar y podríamos pasarle un objeto de esa clase al método minimizador. Una interfaz se define similarmente a una clase, sólo que sus métodos sólo están declarados, es decir, no están implementados. Por lo tanto, las interfaces no son clases y, por tanto, no se pueden instanciar objetos de una interfaz, sino de una clase que implemente la interfaz.

Por ejemplo, para definir una interfaz que lleva una función, escribiríamos:

   interface Funcion{

       double f(double x);

   }

Aquí, la función f(x) está declarada, pero no está implementada. Una clase que implementa esta interfaz podría ser la siguiente:

   class Funcion1 implements Funcion{

         public double f(double x){

           return 1+x+2*x*x;

         }

   }

y un método que utiliza la interfaz sería:

   double evalua(double x, Funcion portador){

     double valor=portador.f(x);

     return valor;

   }

Nótese que aquí el argumento no es un objeto de la clase Funcion, sino de una clase que implemente dicha interfaz.

El siguiente ejemplo es un programa completo donde se implementa la interfaz anterior tres veces, con tres funciones distintas, que se evalúan en un punto y se muestra el resultado (ver figura A.24.).

  public class EjemploJava1 extends Activity {

    TextView tv;

     @Override

     public void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);

         setContentView(R.layout.main);

         tv= (TextView) findViewById(R.id.textView);

         tv.setText("Ejemplo de interfaz " +

             "\n\n Se implementan tres funciones distintas");

         double a=0.5;

         class Funcion1 implements Funcion{

           public double f(double x){

           return 1+x+2*x*x;

           }

         }

         Funcion1 miF1 = new Funcion1();

         double valor=evalua(a, miF1);

         tv.append("\n\n Valor de miF1 = "+ valor);

         class Funcion2 implements Funcion{

           public double f(double x){

           return 1/(1+2*x*x);

           }

         }

         Funcion2 miF2 = new Funcion2();

         valor=evalua(a, miF2);

         tv.append("\n\n Valor de miF2 = "+ valor);

         class Funcion3 implements Funcion{

           public double f(double x){

           return Math.atan(x);

           }

         }

         Funcion3 miF3 = new Funcion3();

         valor=evalua(a, miF3);

         tv.append("\n\n Valor de miF3 = "+ valor);

     }

     // metodo para evaluar una funcion

     // proporcionada en la interfaz Funcion

     double evalua(double x, Funcion portador){

       double valor=portador.f(x);

       return valor;

    }

}

  // interfaz que lleva una funcion

  interface Funcion{

    double f(double x);

 }

    double evalua(double x, Funcion portador){

       double valor=portador.f(x);

       return valor;

    }

}

  // interfaz que lleva una funcion

  interface Funcion{

    double f(double x);

  }

Figura A.24. Uso de una interfaz para evaluar distintas funciones en un método.

Otro ejemplo del uso de interfaces es el siguiente. Trabajando con arrays 2D o matrices encontramos a menudo bloques comunes del tipo:

   for (int i=0;i<miArray.length;i++){

     for(int j=0;j<miArray[i].length;j++){

        // instrucciones

         ...

      }

   }

El bloque común del doble bucle podría pasarse a un método recorreArray(), cuyo argumento serían las instrucciones a realizar. Esto puede hacerse con una interfaz con un método manipula, como en el siguiente programa. La interfaz, Manipulador, está implementada por dos clases y los objetos de esas clases se pasan al método recorreArray()que contiene el bucle. El resultado se ve en la figura A.25..

Figura A.25. Uso de una interfaz para manipular matrices.

  public class EjemploJava1 extends Activity {

    TextView tv;

     @Override

     public void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);

         setContentView(R.layout.main);

         tv= (TextView) findViewById(R.id.textView);

         tv.setText("Ejemplo de interfaz");

         // array bidimensional

         double[][] miArray;

         miArray=new double[4][3];

         class Mani1 implements  Manipulador{

           public void manipula(double[][] a,int i, int j){

              a[i][j]=10*i+j;

           }

         }

         Mani1 m1= new Mani1();

         recorreArray(miArray,m1);

         class Mani2 implements  Manipulador{

           public void manipula(double[][] a,int i, int j){

              tv.append("\n a("+i+","+j+") = "+a[i][j]);

           }

         }

         Mani2 m2= new Mani2();

         recorreArray(miArray,m2);

     }

     // metodo para realizar acciones sobre un array

     // usando la interfaz Manipulador

     void recorreArray(double[][] miArray, Manipulador m){

       for (int i=0;i<miArray.length;i++){

         for(int j=0;j<miArray[i].length;j++){

              m.manipula(miArray,i,j);

               }

            }

         }

  }

   // interfaz para manipular un array

   interface Manipulador{

         void manipula(double[][] a,int i,int j);

   }

Las clases internas Mani1 y Mani2 que implementan la interfaz Manipulador son ejemplos de clases locales, que sólo son visibles dentro de un bloque de código. En este caso, sólo se necesita instanciar un objeto de estas clases, por lo que esta implementación se podría haber hecho utilizando clases anónimas, tratadas en la siguiente sección.

A.20. Clases anónimas

Cuando sólo se necesita un objeto de la clase, por ejemplo para implementar una interfaz, no es realmente necesario definir una clase completa. Se puede utilizar una clase anónima, es decir, que no tiene nombre, instanciando directamente un objeto de la clase. Por ejemplo:

   Interfaz inter= new Interfaz(){

   // implementacion

   ...

   };

Nótese que aquí no se está creando un objeto de la clase Interfaz, porque las interfaces no son clases, sino que se está creando un objeto de una clase anónima que no tiene nombre y que implementa la interfaz.

En el siguiente programa implementamos la interfaz Funcion de la sección anterior usando clases anónimas, el resultado es exactamente el mismo de la figura A.24.

  public class EjemploJava1 extends Activity {

    TextView tv;

     @Override

     public void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);

         setContentView(R.layout.main);

         tv= (TextView) findViewById(R.id.textView);

         tv.setText("Ejemplo de interfaz " +

             "\n\n Se implementan tres funciones distintas");

         double a=0.5;

         Funcion miF1= new Funcion(){

           public double f(double x){

              return 1+x+2*x*x;

           }

         };

         double valor=evalua(a, miF1);

         tv.append("\n\n Valor de miF1 = "+ valor);

         Funcion miF2 = new Funcion(){

           public double f(double x){

              return 1/(1+2*x*x);

           }

         };

         valor=evalua(a, miF2);

         tv.append("\n\n Valor de miF2 = "+ valor);

         Funcion miF3 = new Funcion(){

           public double f(double x){

              return Math.atan(x);

           }

         };

         valor=evalua(a, miF3);

         tv.append("\n\n Valor de miF3 = "+ valor);

     }

     // metodo para evaluar una funcion

     // proporcionada en la interfaz Funcion

    double evalua(double x, Funcion portador){

       double valor=portador.f(x);

       return valor;

    }

  }

   // interfaz que lleva una funcion

   interface Funcion{

     double f(double x);

   }

Como descubrimos al examinar este ejemplo, en realidad tampoco es necesario darle nombre a los objetos miF1, miF2, miF3 de la clase anónima que implementa la interfaz Funcion, sino que bastaría incluir su definición directamente como argumento del método evalua(), es decir:

   double valor=evalua(a, new Funcion(){

        public double f(double x){

           return 1+x+2*x*x;

        }

   });

Obtenemos, entonces, la siguiente versión equivalente del mismo programa que ilustra las posibilidades que ofrece el lenguaje Java para definir un método, dentro del argumento de otro método.

  public class EjemploJava1 extends Activity {

    TextView tv;

     @Override

     public void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);

         setContentView(R.layout.main);

         tv= (TextView) findViewById(R.id.textView);

         tv.setText("Ejemplo de interfaz " +

             "\n\n Se implementan tres funciones distintas");

         double a=0.5;

         double valor=evalua(a, new Funcion(){

           public double f(double x){

              return 1+x+2*x*x;

           }

         });

         tv.append("\n\n Valor de miF1 = "+ valor);

         valor=evalua(a, new Funcion(){

           public double f(double x){

              return 1/(1+2*x*x);

           }

         });

         tv.append("\n\n Valor de miF2 = "+ valor);

         valor=evalua(a, new Funcion(){

           public double f(double x){

              return Math.atan(x);

           }

         });

         tv.append("\n\n Valor de miF3 = "+ valor);

     }

Ir a la siguiente página

Report Page