% Activate the following line by filling in the right side. If for example the name of the root file is Main.tex, write
% "...root = Main.tex" if the chapter file is in the same directory, and "...root = ../Main.tex" if the chapter is in a subdirectory.
 
%!TEX root =  ../notas_java.tex

\chapter[Control de Flujo]{Control de Flujo}

\section{Sentencia if}

En cualquier lenguaje de programación es habitual tener que comprobar si se cumple una cierta condición. La forma normal de conseguirlo es empleando una construcción de la forma:

\begin{verbatim}
    SI   condición_se_cumple   ENTONCES   pasos_a_dar
    SINO pasos_alternos
\end{verbatim}

Esta construcción se encuentra en la mayoría de los lenguajes y es conocida como intrusiones condicionales. En el caso de C, la forma exacta será empleando if (si, en inglés), seguido por la condición entre paréntesis, e indicando finalmente entre llaves los pasos que queremos dar si se cumple la condición, así :

    if (condición)  { sentencias }

Por ejemplo,

\begin{verbatim}
    if (x == 3)  {
      System.out.println( "El valor es correcto" );
      resultado = 5;
    }
\end{verbatim}

Nota: Si solo queremos dar un paso en caso de que se cumpla la condición, no es necesario emplear llaves. Las llaves serán imprescindibles solo cuando haya que hacer varias cosas:

\begin{verbatim}
    if (x == 3)
      System.out.println( "El valor es correcto" );
\end{verbatim}

Una primera mejora, que también permiten muchos lenguajes de programación, es indicar qué hacer en caso de que no se cumpla la condición. Sería algo parecido a

\begin{verbatim}
    SI  condición_a_comprobar  ENTONCES  pasos_a_dar  
    EN_CASO_CONTRARIO  pasos_alternativos
\end{verbatim}

\noindent
que en  Java escribiríamos así:

\begin{verbatim}
    if (condición)  { sentencias1 }   else   { sentencias2 }
\end{verbatim}

Por ejemplo,

\begin{verbatim}
    if (x == 3)  {
      System.out.println( "El valor es correcto" );
      resultado = 5;
    }
    else  {
      System.out.println( "El valor es incorrecto" );
      resultado = 27;
    }

\end{verbatim}

\subsection{Ejemplo Mayor Menor}
El siguiente ejemplo  permite calcular dado tres números cual es el mayor y cual es el menor de ellos.

\begin{verbatim}
public class mayor_menor {

    static public void main (String args[])
    {
      int a, b, c, d;

      a = 4; b = 2; c = 3;
      d = (a > b) ?  a : b;
      d = (d > c) ?  d : c;

      System.out.println("el Mayor es " + d);


      // otra forma

      if(a> b) d = a;
      else d = b;
      if(d< c) d = c;

      System.out.println("el Mayor es " + d);

    }
}
\end{verbatim}

\subsection{Ejemplo Triángulo}
Este ejemplo nos permite determinar dado los tres lados de un triángulo, si es un triángulo Equilátero, Escaleno  Isósceles y calcula además del tipo de triángulo los ángulos internos del mismo. Toda la clase se presenta como un objeto

El diagrama UML para este ejemplo es:

\begin{center}
\begin{tabular}{|c|}
\hline
\textbf{Triangulo} \\
\hline
- a : Double \\
- b : Double \\
- c : Double \\
- A : Double \\
- B : Double \\
- C : Double \\
\hline
<<constructor>> Triangulo(Double, Double, Double)\\
+ EsUnTriangulo(double unaA, double unaB, double unaC): boolean\\
+ info():String \\
+ Area() : Double\\
+ Perimetro() : Double\\
+ toString() : String\\
\hline
\end{tabular}
\end{center}

\begin{verbatim}
package Capitulo_4.Triangulos;

/**
 *
 * @author calderon
 */
public class Triangulo {
    private double a;
    private double b;
    private double c;
    private double A;
    private double B;
    private double C;
    
    public Triangulo(double unaA, double unaB, double unaC) {
        if(EsUnTriangulo(unaA, unaB, unaC) ) {
            a = unaA;
            b = unaB;
            c = unaC;
            
            C = Math.acos((a*a + b*b - c*c)/(2.0f*a*b));
            A = Math.acos((c*c + b*b - a*a)/(2.0f*c*b));
            B = Math.acos((a*a + c*c - a*a)/(2.0f*a*c));
            
            A *= 180.0f/Math.PI;
            B *= 180.0f/Math.PI;
            C *= 180.0f/Math.PI;
            
        }
        else {
            a= -1;
            b= -1;
            c= -1;
        }
    }
    
    public boolean EsUnTriangulo(double unaA, double unaB, double unaC) {
        if(unaA < 0) return false;
        if(unaB < 0) return false;
        if(unaC < 0) return false;
        
        if(unaA + unaB >= unaC) return true;
        if(unaB + unaC >= unaB) return true;
        if(unaC + unaB >= unaA) return true;
        return false;
    }
    
    public String info() {
        String aux;
        
        aux = "Los lados del triangulo son a = " +a + " b = " + b + " c = " + c +"\n"; 
        aux += "Los angulos son A = " + A + " B = " + B + " C = " + C +"\n";     
        
        if(a == b && a == c) 
            aux += "Es un triangulo Equilatero \n";
        else if(a == b || a == c || b == c) 
            aux += "Es un triangulo Isoceles \n";
        else aux += "Es un triangulo Escaleno \n";
        
        if(A == 90 || B == 90 || C == 90)
            aux += "Adicionalemte es un triangulo Rectangulo \n";
        
        aux += "El area del triangulo es " + Area() + " y el perimetro es " + 
                Perimetro();
        
        return aux;
    }
    
    public double Area() {
        double s = (a + b + c)/2.0f;
        double area;
        area = (double)Math.sqrt(s*(s-a)*(s-b)*(s-c));
        return area;
    }
    
    public double Perimetro() {
        return (a+b+c);
    }
    
    @Override
    public String toString() {

        if(a < 0 && b < 0 && c <0)
            return "Los lados proporcioandos no forman un triangulo";
        else
            return info();
    }
    
}
\end{verbatim}

\subsection{Ejemplo Cuadrática}
Para una ecuación cuadrática de la forma $f(x)=Ax^2+Bx + C $, calcular los de $x$ que hacen $f(x)=0$ utilizando la formula general

\begin{equation*}
x = \frac{-B \pm  \sqrt{B^2 - 4 A C}}{2 A}
\end{equation*}  

Comenzamos por escribir una clase para manejar los números complejos de acuerdo con el siguiente diagrama UML

\begin{center}
\begin{tabular}{|c|}
\hline
\textbf{Complejo} \\
\hline
- Real : Double \\
- Imag : Double \\
\hline
<<constructor>> Complejo(Double, Double)\\
+ toString() : String\\
\hline
\end{tabular}
\end{center}

El código correspondiente para los complejos es:

\begin{verbatim}
package Capitulo_4.Ecuacion_cuadratica;

/**
 *
 * @author calderon
 */
public class Complejo {
    private double Real;
    private double Imag;
    
    public Complejo(double unR, double unC) {
        Real = unR;
        Imag = unC;
    }
    
    @Override
    public String toString() {
        String aux;
        
        if(Imag > 0) 
            aux = Real + " + " + Imag + " j \n";
        else if (Imag ==0)
            aux = Real + "\n";            
        else 
            aux = Real + " - " + Imag*(-1.0) + " j \n";
        return aux;
    }
    
}
\end{verbatim}

El Diagrama UML para la clase Cuadrática es:

\begin{center}
\begin{tabular}{|c|}
\hline
\textbf{Cuadratica} \\
\hline
- A : Double \\
- B : Double \\
- C : Double \\
- x1 : Complejo \\
- x2 : Complejo \\
\hline
<<constructor>> Cuadratica(Double, Double, Double)\\
+ Solucion() : void\\
+ toString() : String\\
\hline
\end{tabular}
\end{center}

\noindent
La solución en Java queda

\begin{verbatim}
package Capitulo_4.Ecuacion_cuadratica;

/**
 *
 * @author calderon
 */
public class Cuadratica {
    private double A, B, C;
    private Complejo x1, x2;
    
    public Cuadratica(double unaA, double unaB, double unaC) {
        A = unaA;
        B = unaB;
        C = unaC;
        Solucion();
    }
    
    public void Solucion() {
        double D;
        
        D = B*B - 4.0*A*C;
        
        if(D>0) {
            x1 = new Complejo((-B + Math.sqrt(D))/(2.0*A), 0);
            x2 = new Complejo((-B - Math.sqrt(D))/(2.0*A), 0);
        }
        
        else {
            x1 = new Complejo(-B /(2.0*A), +Math.sqrt(-D)/(2.0*A));
            x2 = new Complejo(-B /(2.0*A), -Math.sqrt(-D)/(2.0*A));
            
        }
    }
    
    @Override
    public String toString() {
        String aux;
        
        aux  = x1.toString() + x2.toString();
        
        return aux;
    }
    
}
\end{verbatim}

\subsection{Ejemplo Caída Libre}
Un objeto es lanzado con una velocidad inicial $v_i = 20$ m/s hacia arriba. Determinar a) La altura máxima a la que llega y b) los tiempos en que el objeto esta a la mitad de la altura máxima.

Para este ejemplo utilizaremos las clases Complejo y Cuadratica del ejemplo anterior las cuales se introduces como tipos de objetos de la clase. En el siguiente diagrama UML se da la descripción de esta implementación.

\begin{center}
\begin{tabular}{|c|}
\hline
\textbf{CaidaLibre} \\
\hline
- vi : Double \\
- y0 : Double \\
- g : Double \\
\hline
<<constructor>> CaidaLibre(Double, Double)\\
+ hmax() : Double\\
+ tiempos() : String\\
+ toString() : String\\
\hline
\end{tabular}
\end{center}

La implementación en Java queda de la siguiente manera

\begin{verbatim}
package Capitulo_4.CaidaLibre;

/**
 *
 * @author calderon
 */
public class CaidaLibre {
    private double vi, y0, g;
    
    public CaidaLibre(double unaY, double unaV) {
        vi = unaV;
        y0 = unaY;
        g = 9.8;
    }
    
    public double hmax() {
        return vi*vi/2.0/g;
    }
    
    public String tiempos() {
        Cuadratica a = new Cuadratica(-0.5*g, vi, y0 - 0.5*hmax());
        return a.toString();
    }
    
    public String toString() {
        String aux = "";
        
        aux += "Para un objeto que se lanza desde una altura de " + y0 + " mts\n";
        aux += "con una velocidad inicial de v0 = " + vi + " mts/seg \n";
        aux += "\n";
        aux += "La altura maxima que alcanza es " + hmax();
        aux += "\n";
        aux += "Los tiempos en los cuales esta a la mitad de la altura maxima son \n";
        aux += tiempos();
        aux += "\n";       
        
        return aux;
    }
}
\end{verbatim}

\subsection{Ejemplo Suma de dígitos}

Determinar si la suma de un número de 4 digitos es igual a 21

\begin{verbatim}
import java.util.Scanner;

public class suma_21 {
    static public void main(String args[]) {
        int n1, n2, n3, n4, suma, n, n0;
        System.out.printf("Dame un numero entero ");
        Scanner entrada = new Scanner(System.in);
        n0= entrada.nextInt();

        n = n0%10000;    // se queda solamente con la ultimas 4 cifras de n

        n1 = n/1000;    // calcula n1 como la division entera
        n %= 1000;      // se queda solamente con las ultimas 3 cifras de n

        n2 = n/100;     // calcula n2 como la division entera
        n %= 100;       // se queda solamente con las ultimas 2 cifras de n

        n3 = n/10;      // calcula n3 como la division entera
        n4 = n%10;      // se queda con el utimo digito

        suma = n1+n2+n3+n4;
        if(suma == 21) System.out.printf("La suma es igual a 21\n");
        else System.out.printf("Sigue intentando la suma es %d\n", suma);
    }
}
\end{verbatim}

\subsection{Operador Condicional}

Existe una construcción adicional, que permite comprobar si se cumple una condición y devolver un cierto valor según si dicha condición se cumple o no. Es lo que se conoce como el ``operador condicional (?)'':

\begin{verbatim}
    condicion ? resultado_si cierto : resultado_si_falso
\end{verbatim}

Es decir, se indica la condición seguida por una interrogación, después el valor que hay que devolver si se cumple la condición, a continuación un símbolo de ``dos puntos'' y finalmente el resultado que hay que devolver si no se cumple la condición.

Es frecuente emplearlo en asignaciones (aunque algunos autores desaconsejan su uso porque puede resultar menos legible que un ``if''), como en este ejemplo:

    x = (a == 10) ? b*2 : a ;

En este caso, si a vale 10, la variable tomará el valor de b*2, y en caso contrario tomará el valor de a. Esto también se podría haber escrito de la siguiente forma, más larga pero más legible:

\begin{verbatim}
    if (a == 10)  x = b*2; else x = a;
\end{verbatim}

El siguiente es un ejemplo donde se utilizan las expresiones condicionales.

\begin{verbatim}
public class expresion_condicional {
    static public void main(String args[]) {

        int x =1, y;

        /*
         * La condicional 
        */

        if(x==1) y = 20;
        else y = 10;

        System.out.printf("y = %d\n", y);

        /*
         * se puede escribir como 
         */

        y=0;

        y = (x==1) ? 20 : 10;        
        System.out.printf("y = %d\n", y);

        /*
         *Otro ejemplo es
         */

        if(x==1) System.out.printf("en Auto");
        else System.out.printf("en bici");

        /**
         *Utilizando expresiones
         */

        System.out.printf((x==1) ? "en Auto" : "en bici");
    }
}
\end{verbatim}


\section{Comparando datos}

Si comparamos tipos primitivos con los operadores == o != el resultado es el esperado. Sin embargo, si comparamos objetos con estos dos operadores el resultado puede no ser el esperado. Tenemos el ejemplo siguiente:

\begin{verbatim}
public class Equivalencia {
   public static void main(String[] args) {
     Integer n1 = new Integer(47);
     Integer n2 = new Integer(47);
  
     System.out.println("n1==n2: "+ (n1 == n2));
     System.out.println("n1!=n2: "+ (n1 != n2));
 
     String s1 = new String("Hola");
     String s2 = new String("Hola");
 
     System.out.println("s1==s2: "+ (s1 == s2));
     System.out.println("s1!=s2: "+ (s1 != s2));
 }
}
\end{verbatim}

Si lo ejecutamos el resultado es:

\begin{verbatim}
n1==n2: false
n1!=n2: true
s1==s2: false
s1!=s2: true
\end{verbatim}

Esto se debe a que los operadores == y != comparan referencias, no valores. La referencia de n1 está almacenada en un lugar de la memoria y la de n2 en otra, lo mismo para s1 y s2. Recuerda que cada vez que se crea un objeto con new se le asigna un espacio de memoria en el cúmulo.

Para comparar objetos, no tipos primitivos, tenemos el método equals(), que se puede utilizar siempre, ya que está incluido en la clase java.lang.Object que por defecto heredan todas las clases. Este método compara valores en lugar de referencias, modificamos un poco el ejemplo anterior y utilizamos equals():

\begin{verbatim}
public class Equivalencia2 {
   public static void main(String[] args) {
     Integer n1 = new Integer(47);
     Integer n2 = new Integer(47);
  
     System.out.println("n1.equals(n2): "+n1.equals(n2));
 
     String s1 = new String("Hola");
     String s2 = new String("Hola");
 
     System.out.println("s1.equals(s2): "+s1.equals(s2));
   }
}
\end{verbatim}

El resultado es:

\begin{verbatim}
n1.equals(n2): true
s1.equals(s2): true
\end{verbatim}

Otro método para hacer comparación entre objetos es utilizar el comando compareTo, el cual regresa un número entero bajo las siguiente condiciones

\begin{center}
\begin{tabular}{ll}
n1.CompareTo(n2)  & $\rightarrow $ Regresa -1 si n1 es menor que n2 \\
n1.CompareTo(n2)  & $\rightarrow $ Regresa  0  si n1 es igual que n2 \\
n1.CompareTo(n2)  & $\rightarrow $ Regresa  1 si n1 es mayor que n2\\
\end{tabular}
\end{center}

Como ejemplo tenemos

\begin{verbatim}
public class Equivalencia3 {
   public static void main(String[] args) {
     Float n1 = new Float(1.0);
     Float n2 = new Float(2.0);
     Float n3 = new Float(3.0);

     System.out.println(n1.floatValue()+ ", " 
     +n2.floatValue() + " " + n1.compareTo(n2));
     System.out.println(n2.floatValue()+ ", " +n1.floatValue() 
     + " " + n2.compareTo(n1));
     System.out.println(n2.floatValue()+ ", " +n2.floatValue() 
     + " " + n2.compareTo(n2));
   }
}
\end{verbatim}

Estos métodos están definidos en las clases wrapper de los tipos básicos, pero es necesario hacer la extensión en el caso de tipos objetos nuevos.

\subsection{Sobre escritura del método equal()}
Todos los objetos declarados en Java, por default tienen un método llamado equal(). Este método puede ser sobre escrito para hacer comparaciones entre objetos del mismo tipo. 

Para mayor claridad vamos a escribir un objeto que represente una Fracción, cuyo diagrama UML es:

\begin{center}
\begin{tabular}{|c|}
\hline
\textbf{Fraccion} \\
\hline
- numerador : Double \\
- denominador : Double \\
\hline
<<constructor>> Fraccion(Integer, Integer)\\
+ equals(Object ): boolean\\
+ toString() : String\\
\hline
\end{tabular}
\end{center}

La escritura de método equal() queda

\begin{verbatim}
package Capitulo_4.Fraccion_old;

/**
 *
 * @author felix
 */
public class Fraccion {
    private int numerador;
    private int denominador;
    
    public Fraccion(int unN, int unD) {
        numerador = unN;
        denominador = unD;
    }
    
    @Override
    public String toString(){
        String signo;
        signo = (numerador/denominador < 0) ? "-" : "+";
        return signo + Math.abs(numerador) + "/" 
                + Math.abs(denominador); 
    }
    
    @Override
    public boolean equals(Object  b) {
        if(b instanceof Fraccion) {
        
            Fraccion aux = (Fraccion)b;
        
            return denominador == aux.denominador && 
                numerador == aux.numerador;
        }
        return false;
    }
}
\end{verbatim}

La manera de probar el código es

\begin{verbatim}
package Capitulo_4.Fraccion_old;

/**
 *
 * @author felix
 */
public class Prueba {
    static public void main(String args[]) {
        Fraccion a = new Fraccion(-3, 4);
        Fraccion b = new Fraccion(3, 2);
        Fraccion c = new Fraccion(-3, 4);
        
        System.out.println(a + " es igual a " + b + " " + a.equals(b));
        System.out.println(a + " es igual a " + c + " " + a.equals(c));
        
    }
}
\end{verbatim}

Cuya ejecución da como resultado


\begin{verbatim}
+3/4 es igual a +3/2 false
+3/4 es igual a +3/4 true
\end{verbatim}

\section{Sentencia switch}

Si queremos comprobar varias condiciones, podemos utilizar varios if - else - if - else - if encadenados, pero tenemos una forma más elegante en Java de elegir entre distintos valores posibles que tome una cierta expresión.  Su formato es :

\begin{verbatim}
  switch (expresion) {
    case valor1: sentencias1; break;
    case valor2: sentencias2; break;
    case valor3: sentencias3; break;
    ...                                  // Puede haber más valores
}
\end{verbatim}

\subsection{Ejemplo ultimo dígito}
Como ejemplo podemos ver la siguiente implementación en C, que permite calcular cual es el último dígito de un número dado

\begin{verbatim}
public class ejemplo_switch {
    static public void main(String args[]) {
        int d = 243;

        switch(d%10) {
            case 0: System.out.printf("cero ");   break;
            case 1: System.out.printf("uno ");    break;
            case 2: System.out.printf("dos ");    break;
            case 3: System.out.printf("tres ");   break;
            case 4: System.out.printf("cuatro "); break;
            case 5: System.out.printf("cinco ");  break;
            case 6: System.out.printf("seis ");   break;
            case 7: System.out.printf("siete ");  break;
            case 8: System.out.printf("ocho ");   break;
            case 9: System.out.printf("nueve ");  break;
            default : ;
        }

        System.out.printf("Unidades\n");
    }
}
\end{verbatim}

Es decir, después de la orden switch indicamos entre paréntesis la expresión que queremos evaluar. Después, tenemos distintos apartados, uno para cada valor que queramos comprobar; cada uno de estos apartados se precede con la palabra case, indica los pasos a dar si es ese valor el que se da, y terminar con break.

Un ejemplo sería:

\begin{verbatim}
  switch ( x * 10) {
    case 30: printf( "El valor de x era 3" ); break;
    case 50: printf( "El valor de x era 5" ); break;
    case 60: printf( "El valor de x era 6" ); break;
}
\end{verbatim}

también podemos indicar qué queremos que ocurra en el caso de que el valor de la expresión no sea ninguno de los que hemos detallado:

\begin{verbatim}
  switch (expresion) {
    case valor1: sentencias1; break;
    case valor2: sentencias2; break;
    case valor3: sentencias3; break;
    ...                                  // Puede haber más valores
    default: sentencias;                 // Opcional: valor por defecto
}
\end{verbatim}

Por ejemplo, así:

\begin{verbatim}
  switch ( x * 10) {
    case 30: printf( "El valor de x era 3" ); break;
    case 50: printf( "El valor de x era 5" ); break;
    case 60: printf( "El valor de x era 6" ); break;
    default: printf( "El valor de x no era 3, 5 ni 6" ); break;
}
\end{verbatim}

Podemos conseguir  que en varios casos se den los mismos pasos, simplemente eliminado la orden ``break'' de algunos de ellos. Así, un ejemplo algo más completo podría ser:

\begin{verbatim}
  switch ( x ) {
    case 1:
    case 2:
    case 3:
        System.out.printf( "El valor de x estaba entre 1 y 3" );
        break;
    case 4:
    case 5:
        System.out.printf( "El valor de x era 4 o 5" );
        break;
    case 6:
        System.out.printf( "El valor de x era 6" );
        valorTemporal = 10;
        System.out.printf( "Operaciones auxiliares completadas" );
        break;
    default:
        System.out.printf( "El valor de x no estaba entre 1 y 6" );
        break;
}
\end{verbatim}

\subsection{Ejemplo rango letras}

El siguiente ejemplo permite calcular, dada una letra en que rango se encuentra.

\begin{verbatim}
public class rango_letras {
    static public void main(String args[]) {

        char c = 'a';
        
        if(c >= 'A' && c <= 'Z') c += 32;

        switch(c) {
            case 'a' : 
            case 'b' :
            case 'c' :
            case 'd' : System.out.printf("La letra esta entre A y D\n"); break;
            case 'e' :
            case 'f' :
            case 'g' :
            case 'h' : System.out.printf("La letra esta entre E y H\n"); break;
            case 'i' :
            case 'j' :
            case 'k' :
            case 'l' : System.out.printf("La letra esra ebtre I y L\n"); break;
            case 'm' :
            case 'n' :
            case 'o' :
            case 'p' : System.out.printf("La letra esra ebtre M y P\n"); break;
            case 'q' :
            case 'r' :
            case 's' :
            case 't' : System.out.printf("La letra esra ebtre Q y T\n"); break;
            case 'u' :
            case 'v' :
            case 'w' :
            case 'x' : System.out.printf("La letra esra ebtre U y X\n"); break;
            case 'y' :
            case 'z' : System.out.printf("La letra esra ebtre X y Z\n"); break;
            default : System.out.printf("No es un caracter valido\n");
        }

    }
}
\end{verbatim}

Un poco más adelante propondremos ejercicios que permitan afianzar todos estos conceptos.

\section{Sentencia while}
\subsection{while}
Java incorpora varias formas de conseguirlo. La primera que veremos es la orden while, que hace que una parte del programa se repita mientras se cumpla una cierta condición. Su formato será:

\begin{verbatim}
    while (condición) {
        sentencia 1;
        sentencia 2;
        ...
     }
\end{verbatim}

Es decir, la sintaxis es similar a la de if, con la diferencia de que aquella orden realizaba la sentencia indicada una vez como máximo (si se cumple la condición), pero while puede repetir la sentencia más de una vez (mientras la condición sea cierta). Al igual que ocurría con if, podemos realizar varias sentencias seguidas (dar más de un paso) si las encerramos entre llaves:

\begin{verbatim}
    x = 20;
    while ( x > 10) {
      System.out.printf("Aun no se ha alcanzado el valor limite\n");
      x --;
    }
\end{verbatim}

\subsection{do-while}
Existe una variante de este tipo de bucle. Es el conjunto do..while, cuyo formato es:

\begin{verbatim}
    do {
      sentencia1;
      sentencia2;
      ...
    } while (condición)
\end{verbatim}

En este caso, la condición se comprueba al final, lo que quiere decir que las ``sentencias'' intermedias se realizarán al menos una vez, cosa que no ocurría en la construcción anterior (un único while antes de las sentencias), porque si la condición era falsa desde un principio, los pasos que se indicaban a continuación de while no llegaban a darse ni una sola vez.

Un ejemplo típico de esta construcción ``do..while'' es cuando queremos que el usuario introduzca una contraseña que le permitirá acceder a una cierta información:

\begin{verbatim}
    do {
      System.out.printf("Introduzca su clave de acceso\n");
      lee_teclado("%f", &claveIntentada);  // LeerDatosUsuario realmente no existe
    } while (claveIntentada != claveCorrecta)
\end{verbatim}

En este ejemplo hemos la función scanf para leer un número flotante. 

\section{Sentencias do y for}

Una tercera forma de conseguir que parte de nuestro programa se repita es la orden for. La emplearemos sobre todo para conseguir un número concreto de repeticiones.  Su formato es

\begin{verbatim}
    for ( valor_inicial ; condicion_continuacion ; incremento ) {
      sentencias1;
      sentencias2;
      ...
    }
\end{verbatim}

(es decir, indicamos entre paréntesis, y separadas por puntos y coma, tres Ordenes: la primera dará el valor inicial a una variable que sirva de control; la segunda orden será la condición que se debe cumplir para que se repitan las sentencias; la tercera orden será la que se encargue de aumentar -o disminuir- el valor de la variable, para que cada vez quede un paso menos por dar).

Esto se verá mejor con un ejemplo. podríamos repetir 10 veces un bloque de Ordenes haciendo:

\begin{verbatim}
    for ( i=1 ; i<=10 ; i++ ) {
      ...
    }
\end{verbatim}

O bien podríamos contar descendiendo desde el 20 hasta el 2, con saltos de 2 unidades en 2 unidades, así:

\begin{verbatim}
    for ( j = 20 ; j > 0 ; j -= 2 )
      System.out.printf( "%d\n", j );
\end{verbatim}

Nota: se puede observar una equivalencia casi inmediata entre la orden for y la orden while. Así, el ejemplo anterior se podría reescribir empleando while, de esta manera:

\begin{verbatim}
    j = 20;
    while ( j > 0 )
      System.out.printf( "%d\n", j );
      j -= 2;
    }
\end{verbatim}

Precauciones con los bucles: Casi siempre, nos interesará que una parte de nuestro programa se repita varias veces (o muchas veces), pero no indefinidamente. Si planteamos mal la condición de salida, nuestro programa se puede quedar colgado, repitiendo sin fin los mismos pasos.


Se puede modificar un poco el comportamiento de estos bucles con las ordenes break y continue.

La sentencia break hace que se salten las instrucciones del bucle que quedan por realizar, y se salga del bucle inmediatamente. Como ejemplo:

\begin{verbatim}
    for ( i=1 ; i<=10 ; i++ ) {
      System.out.printf( "Comenzada la vuelta " );
      printf( "%d\n", i );
      if (i==8)  break;
      System.out.printf( "Terminada esta vuelta\n" );
    }
    System.out.printf( "Terminado\n"  );
\end{verbatim}

En este caso, no se mostraría el texto Terminada esta vuelta para la pasada con i=8, ni se darían las pasadas de i=9 e i=10, porque ya se ha abandonado el bucle.

La sentencia continue hace que se salten las instrucciones del bucle que quedan por realizar, pero no se sale del bucle sino que se pasa a la siguiente iteración (la siguiente vuelta o pasada). Como ejemplo:

\begin{verbatim}
    for ( i=1 ; i<=10 ; i++ ) {
      System.out.printf( "Comenzada la vuelta\n" );
      System.out.printf( "%d\n", i );
      if (i==8)  continue;
      System.out.printf( "Terminada esta vuelta\n" );
    }
    printf( "Terminado\n"  );
\end{verbatim}

En este caso, no se mostraría el texto Terminada esta vuelta para la pasada con i=8, pero si se darían la pasada de i=9 y la de i=10.

también esta la posibilidad de usar una etiqueta para indicar donde se quiere saltar con break o continue. Solo se debería utilizar cuando tengamos un bucle que a su vez está dentro de otro bucle, y queramos salir de golpe de ambos. Es un caso poco frecuente, así que no profundizaremos más, pero si veremos un ejemplo:

\begin{verbatim}
    for ( i=1 ; i<=10 ; i++ ) {
      System.out.printf( "Comenzada la vuelta\n" );
      System.out.printf( "%d\n", i );
      if (i==8)  break salida;
      System.out.printf( "Terminada esta vuelta\n" );
    }
    System.out.printf( "Terminado\n"  );
    salida:
    ...
\end{verbatim}

En este caso, a mitad de la pasada 8 se saltaría hasta la posición que hemos etiquetado como salida (se define como se ve en el ejemplo, terminada con el símbolo de dos puntos), de modo que no se escribiría en pantalla el texto Terminado (lo hemos saltado).

\subsection{Ejemplo Sumatoria}

Hacer un programa que permita calcular la siguiente sumatoria

$$
S = \sum_{i=0}^{i=64} 2^i
$$

La implementación en Java queda:

\begin{verbatim}
public class sumatoria {
    static public void main (String args[])
    {
      int i=1, s=0;

      // utilizando for()

      for(i=0; i<=30; i++){
        s=((2*s) +1);
        System.out.printf("%d s=%d\n", i, s);
      }

      // utilizando while

      i = 1;
      s = 0;
      while(i <=30)
      {
        s=((2*s) +1);
        System.out.printf("%d s=%d\n", i, s);
        i++;
      }

      // utilizando do-while

      i = 1;
      s = 0;
      do
      {
        s=((2*s) +1);
        System.out.printf("%d s=%d\n", i, s);
        i++;
      }
      while (i<=30);
    }
}
\end{verbatim}

\subsection{Ejemplo comparación for, while, do-while}

El siguiente ejemplo permite hacer una comparación entre la implementación utilizando for y do-while para leer una clave desde teclado.

\begin{verbatim}
import java.util.Scanner;

public class clave {
    static public void main(String args[]) {
        int clave;
        Scanner entrada = new Scanner(System.in);
        // impelementacion utilizando for

        for(;;){
            System.out.printf("Dame tu clave ");
            clave = entrada.nextInt();

            if(clave == 1234) break;
        }

        // implementacion con do-while

        do {
            System.out.printf("Remita su clave nuevamente ");
            clave = entrada.nextInt();        
        } while (clave != 1234);

        System.out.printf("Bienvenido\n");

    }
}
\end{verbatim}

\subsection{Ejemplo Combinaciones}

Escribir un programa que permita imprimir todas las combinaciones de palabra de tres letras que se pueden escribir utilizando las letras del alfabeto. Así por ejemplo la salida de este código es

AAA
AAB
AAC
...
ABA
ABC

etc.

\begin{verbatim}
public class combinaciones {
    static public void main(String args[]) {
        int i, j, k, n=1;
        int letra = 'A';

        for(i=0; i<3; i++){
            for(j=0; j<3; j++){
                for(k=0; k<3; k++)
                    System.out.printf("%02d.- %c%c%c \n",
                     n++, letra +i, letra+j, letra +k);
            }
        }
    }
}
\end{verbatim}

\subsection{Ejemplo función}

Escribir un programa que permita hacer la siguiente tabulación correspondiente a la función $f(x)= x^2$


\begin{center}
\begin{tabular}{|c|c|}
	\hline
	$x$ & $f(x)$ \\
	\hline
	1 & 1 \\
	2 & 4 \\
	3 & 9 \\
	4 & 16\\
	\hline
\end{tabular}
\end{center}

\begin{verbatim}
public class funcion {
    static public void main(String args[]) 
    {
      int x;

      for(x=1; x<=10; x++)
        System.out.printf("%d^2 = %f \n", x, cuadrado(x));
    }

    // Definicion  de la funcion

    static public float cuadrado(float y)
    {
      return y*y;
    }
}
\end{verbatim}

\subsection{Ejemplo triángulo impreso}

Escribir un programa que permita imprimir un triángulo como el que se muestra a continuación

\noindent
*\\
**\\
***\\
****\\
*****\\
******\\
*******\\

\begin{verbatim}
public class triangulo {
    static public void main(String args[]) {
        int i, j;

        for(i=0; i<20; i++) {
            for(j=0; j<i; j++)
                System.out.printf("*");
            System.out.printf("\n");
        }

    }
}
\end{verbatim}

\section{Iteradores}

Los Iteradores son un patrón de diseño utilizado para recorrer las colecciones. En java es una interfaz denominada Iterator. Esta formado por 3 métodos:

-  boolean hasNext(): retorna true en caso de haber mas elementos y false en caso de llegar al final de iterator

-  Object next(): retorna el siguiente elemento en la iteración

-  void remove(): remueve el ultimo elemento devuelto por la iteración

Una manera de utilizarlos es mediante un arreglo de datos  tal como se muestra en el código donde se declara un arreglo de enteros con la variable val y todos los valores son recorridos por la sentencia ``for(int i: val)".

\begin{verbatim}
    static public void ejemplo03(){
        
        int val[] = new int[] {1,2,3,4,5,6,7,8,9,10};
        
        for(int i: val)
            System.out.println(i);
            
        
    }
\end{verbatim}

Con un equivalente utilizando ciclos dado por

\begin{verbatim}
    static public void ejemplo03(){
        
        int val[] = new int[] {1,2,3,4,5,6,7,8,9,10};
        
        for(int i =0; i<9; i++)
            System.out.println(val[i]);
            
        
    }
\end{verbatim}

En las clases Vector, ArrayList, HashSet y TreeSet un iterador se consigue a través del método: Iterator iterator().  El siguiente es un ejemplo de los iteradores utilizados en las clases ArrayList y Vector

\begin{verbatim}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;

public class Iteradores {
    static public void ejemplo01() {
        ArrayList a = new ArrayList();
        Object x;
        
        a.add(new Integer(3));
        a.add(new Double(4));
        a.add(new Character('x'));
        a.add(new String("Hola"));
        
        for (Iterator it = a.iterator(); it.hasNext();){
            x = it.next();
            System.out.println(x);
        }      
        
        for(Object b: a) 
            System.out.println(b);    
    }

    static public void ejemplo02() {
        Vector a = new Vector();
        Object x;
        
        a.add(new Integer(3));
        a.add(new Double(4));
        a.add(new Character('x'));
        a.add(new String("Hola"));
        
        for (Iterator it = a.iterator(); it.hasNext();){
            x = it.next();
            System.out.println(x);
        }      
        
        for(Object b: a) 
            System.out.println(b);
    }
    
    static public void main(String args[]) {
        ejemplo02();
    }
}
\end{verbatim}

\subsection{Ejemplo Agenda } 

Escribir un código para crear una agenda. La agenda tendrá información del nombre de la persona, dirección y Teléfono.

Para comenzar definiremos un objeto llamado Persona con los atributos que se mencionan y con los métodos que se muestran en el siguiente diagrama UML

\begin{center}
\begin{tabular}{|c|}
\hline
\textbf{P e r s o n a} \\
\hline
- Nombre : String \\
- ApellidoPaterno : String \\
- ApellidoMaterno : String \\
- Domicilio : String\\
- Telefono : String\\ 
\hline
<<constructor>> Persona(String, String, String, String, String)\\
+ toString() : String\\
+ toequals(Object) : boolean\\
\hline
\end{tabular}
\end{center}

La codificación en Java del Objeto Persona es:

\begin{verbatim}
package Capitulo_4.Agenda;

public class Persona {
    private String Nombre;
    private String ApellidoPaterno;
    private String ApellidoMaterno;
    private String Domicilio;
    private String Telefono;
    
    public Persona(String unNombre, String unPaterno, String unMaterno, 
            String unDomicilio, String unTelefono) {
        Nombre = unNombre;
        ApellidoPaterno = unPaterno;
        ApellidoMaterno = unMaterno;
        Domicilio = unDomicilio;
        Telefono = unTelefono;
    }
    
    @Override
    public String toString() {
        String aux;
        
        aux = "Nombre    : " + Nombre + 
              " " + ApellidoPaterno + 
              " " + ApellidoMaterno + "\n" +
              "Domicilio : " + Domicilio + "\n"+
              "Telefono  : " + Telefono + "\n\n";
           
        return aux;
    }
    
    @Override
    public boolean equals(Object O){
        Persona a = (Persona) O;
        
        return (this.Nombre.equals(a.Nombre) || 
                this.ApellidoPaterno.equals(a.ApellidoPaterno) ||
                this.ApellidoMaterno.equals(a.ApellidoMaterno));
    }
}
\end{verbatim} 

El diagrama UML para el objeto Agenda es:

\begin{center}
\begin{tabular}{|c|}
\hline
\textbf{A  g  e  n  d  a} \\
\hline
- datos : ArrayList $<$Persona$>$ \\
\hline
<<constructor>> Agenda()\\
+ agrega(String, String, String, String, String) \\
+ busca(String) : String\\
+ CreaAgenda() : void\\
+ toString(): String\\
\hline
\end{tabular}
\end{center}

La implementación para el objeto Agenda en Java es:

\begin{verbatim}
package Capitulo_4.Agenda;

import java.util.ArrayList;
import java.util.Iterator;

public class Agenda {
    private ArrayList<Persona> datos;
    
    public Agenda() {
        datos = new ArrayList();
        CreaAgenda();
    }
    
    public void CreaAgenda() {
        agrega("Felix", "Calderon", "Solorio", "Morelia", "xxxxxx");
        agrega("Juan", "Lopez", "Dias", "Un calle", "un telefono");
    }
    
    public void agrega(String unNombre, String unPaterno, 
    String unMaterno, String unDomicilio, String unTelefono) {
        Persona a = new Persona(unNombre, unPaterno, 
        unMaterno, unDomicilio, unTelefono);
        datos.add(a);
    }
    
    public String busca(String nombre) {
        Persona aux = new Persona(nombre, nombre, nombre, "" , "");
        
        for(Persona a:datos) {
            if(a.equals(aux)) return a.toString();
        }
        
        return "Persona no encontrada\n";
    }
    
    @Override
    public String toString() {
        String aux = ""; 
        Persona x;
        Iterator it;
        for (it = datos.iterator(); it.hasNext();){
            x = (Persona) it.next();
            aux += x;
        }
        return aux;
    }
}
\end{verbatim}

Finalmente para la ejecución escribimos la clase a la que generalmente llamamos prueba.

\begin{verbatim}
package Capitulo_4.Agenda;

public class Prueba {
    static public void main(String args[]){
        Agenda mi_agenda = new Agenda();
        System.out.println(mi_agenda);
        
        
        System.out.println(mi_agenda.busca("Felix"));
    }
}
\end{verbatim}

\section{Recursividad}

Un método recursivo es un método que se llama a si mismo directa o indirectamente o a través de otro método. Un ejemplo interesante de recursion es la función factorial. La definición de factorial esta dada por el producto: 

$$
n! = n*(n-1)*(n-2)*...*3*2*1
$$

Note que esta definición la podemos escribir de manera recursiva como:
\[
n! = n*(n-1)!
\]

En común representar a las funciones recursivas en dos pasos. El primero de ellos es conocido como Paso Base y Paso Recursivo. El primero es la condición más sencilla de la definición y normalmente es trivial hacer el cálculo y el segundo es el paso recursivo. Para el caso del Factorial tenemos

\noindent
$factorial(N)$

\noindent
Base

Si $N=1$ el factorial es 1

\noindent
Paso Recusivo

Si no $n \times factorial(N-1)$
 

Este método lo podemos escribir  en Java  como

\begin{verbatim}
public class Factorial {
    
    static public void main(String args[]) {
        int n = 10;
        System.out.printf("Factorial de %d es %d\n", n, factorial(n) );
    }
    
    static public int factorial(int N){
        if(N==1) return 1;
        else return N*factorial(N-1);
    }
 \end{verbatim}

Otro ejemplo de definición recursiva es la multiplicación de números naturales. El producto a*b, donde a y b son enteros positivos, puede definirse como

\noindent
$Multiplica (x, y)$

\noindent
Base

Si $y=1$  el producto es y

\noindent
Paso Recusivo

Si no el resultado es $x + Multiplica(x, y-1)$

\begin{verbatim}
public class Multiplica {

    static public void main(String args[])
    {
      int x=4, y=5;
      System.out.printf("%d\n", multiplica(4,5));
    }

    static public int multiplica(int x, int y)
    {
       if(y == 1) return x;
       else return (x + multiplica(x,y-1));
    }
}
\end{verbatim}

\subsection{Torres de Hanoi}

El ejemplo más conocido, de recursividad entre los programadores, es el problema de las torres de Hanoi. Para este juego, se tienen tres postes (A, B, C) y un conjunto n de discos colocados de mayor a menor diámetro en alguno de los postes, por ejemplo el poste A. La meta es mover todos los discos del poste A al poste C con las siguientes restricciones: 

1.- En cada movimiento solo se puede tomar un disco y colocarlo en cualquier poste y 
2.- No se debe colocar, un en un poste,  un disco de diámetro mayor sobre un disco de diámetro menor.

La definición recursiva de las torres de Hanoi es:

\noindent
$mover\_discos(origen, auxiliar, destino, discos)$

\noindent
Base

Si $discos=1$ Mover un disco de $origen$ a $destino$

\noindent
Paso recursivo

Mover $n-1$ discos de $origen$ a $auxiliar$ 

Mover 1 disco de $origen$ a $destino$

Mover $n-1$ discos de $auxiliar$ a $destino$

\noindent
La implementación en C queda

\begin{verbatim}
public class Torres_Hanoi {

    static int movtos ;

    static public void main(String args[])
    {
       movtos = 1;
       mover_discos('A', 'B', 'C', 4);
    }

    static public void mover_discos(char a, char b, char c, int n)
    {
        if (n > 0) {
            mover_discos(a, c, b, n - 1);
            System.out.printf("%d Mover un disco del poste 
            %c al poste %c\n", movtos++, a, c);
            mover_discos(b, a, c, n - 1);
        }
    }
}
\end{verbatim}


La solución con tres discos es:

\begin{verbatim}
1 Mover un disco del poste A al poste C
2 Mover un disco del poste A al poste B
3 Mover un disco del poste C al poste B
4 Mover un disco del poste A al poste C
5 Mover un disco del poste B al poste A
6 Mover un disco del poste B al poste C
7 Mover un disco del poste A al poste C
\end{verbatim}

\subsection{Método de Bisecciones}

Este método es conocido también como de corte binario. de partición en dos intervalos iguales o método de Bolzano. Es un método de búsqueda incremental donde el intervalo de búsqueda se divide en dos. Si la función cambia de signo sobre un intervalo, se calcula el valor en el punto medio. El nuevo intervalo de búsqueda será aquel donde el producto de la función cambie de signo.

La definición recursiva para este algoritmos es:

Dada una función $f(x)$ y un intervalo $[inicio,fin]$ de búsqueda donde existe un cruce por cero, podemos notar que $f(a) \times f(b) < 0$ porque la función en el intervalo pasa de menos a mas o de mas a menos debido a que cruza por cero. Así tenemos:

\noindent
$Biseccion(inicio, fin)$

\noindent
Base

Si $b-a < \epsilon$ la solución es $(a+b)/2$

\noindent
Paso Recusivo

Calcular $mitad =\frac{inicio+fin}{2}$ 

Si  $f(inicio)\times f(mitad) <0$ entonces $Biseccion(inicio,mitad)$

Si no $Biseccion(mitad,fin)$
La implementación recursiva de este algoritmo en Java es:

\begin{verbatim}
public class Bisecciones {
    static public void main(String args[])
    {
      System.out.printf("La solucion esta en %f\n", Biseccion(0,1));
    }

    static public double Biseccion(double ini, double fin)
    {
      double mitad;    mitad = (fin + ini)/2.0;
      System.out.printf("f_1(%f) = %f f_m(%f) = %f f_2(%f) = %f\n", 
              ini, funcion(ini), mitad, funcion(mitad), fin, funcion(fin));
      if((fin - ini) > 1e-12)
      {
        if(funcion(ini)*funcion(mitad) < 0)
          return Biseccion(ini, mitad);
        else return Biseccion(mitad, fin);
      }
      else return (mitad);
    }

    static public double funcion(double x)
    {
      return (x - Math.cos(x));
    }
}
\end{verbatim}

\subsubsection{Ejemplo}

Considere la función $f(x) = x-cosx$, a priori sabemos que la función tiene un cruce por cero en el intervalo $[0,1]$, así que nuestra búsqueda se concentrará en este.

\begin{flushleft}
\begin{tabular}{|c|c|c|c|c|c|c|}
  \hline
  % after \\: \hline or \cline{col1-col2} \cline{col3-col4} ...
iter & inicio & mitad & fin &  f(ini) &  f(mitad) & f(fin) \\
  \hline
0 &  0.0 &  0.5 &  1.0 & -1.0 & -0.3775 & 0.4596 \\
1 & 0.5 & 0.75 & 1.0 & -0.3775 & 0.0183 & 0.4596 \\
2 &  0.5 & 0.625 & 0.75 & -0.3775 & -0.1859 & 0.0183 \\
3 & 0.625 & 0.6875 & 0.75 & -0.1859 & -0.0853 & 0.0183 \\
4 & 0.6875 & 0.71875 &  0.75 & -0.0853 & -0.0338 & 0.0183 \\
5 & 0.71875 & 0.734375 & 0.75 & -0.0338 & -0.0078 & 0.0183 \\
6 &  0.734375 & 0.7421875 & 0.75 & -0.0078 & 0.0051 & 0.0183 \\
7 & 0.734375 & 0.73828125 & 0.7421875 & -0.0078 & -0.0013 & 0.0051\\
8 & 0.73828125 & 0.740234375 & 0.7421875 & -0.0013 & 0.0019 &
0.0051 \\
9 & 0.73828125 & 0.7392578125 & 0.740234375 & -0.0013 & 0.0002 &
0.0019\\
  \hline
\end{tabular}
\end{flushleft}


\section{Assertions}

Definimos una aserción o acertó como una expresión que siempre es verdadera y es inadmisible que sea diferente. En Java cuando queremos proteger un código para que no se den valores fuera de un rango utilizamos el comando assert, el cual tiene la siguiente sintaxis

assert Expresion1;
assert Expresión1:Expresión2;

En cualquiera de los dos casos Expresión1 tiene que ser una expresión booleana o se producirá un error de compilación. Cuando se evalúa un aserto que solo tenga Expresión1, se comprueba la veracidad de la expresión y si es verdadera se continúa la ejecución del programa, pero si es falsa, se lanza una excepción de tipo AssertionError. Si el aserto contiene además una Expresión2 y Expresión1 es falsa, se evalúa Expresion2 y se le pasa como parámetro al constructor del AssertionError (Si Expresion1 se evalúa como cierto, la segunda expresión no se evalúa). 

A continuación se muestra un ejemplo del uso de aserciones para limitar a que un código solo acepte números entre 0 y 10.

\begin{verbatim}
import java.util.Scanner;

public class Aserciones
{
     public static void main( String args[] )
     {
        Scanner input = new Scanner( System.in );
        
        System.out.print("Dame un numero entre 0 y 10: " );
 
        int numero = input.nextInt();
        
        // genera un mensaje de error si el numero no esta en rango
        assert ( numero >= 0 && numero <= 10 ) : "Numero incorrecto: " + numero;
        
        System.out.println( "Me diste el numero "+ numero );
     } 
} 
\end{verbatim}

Para que se activen las aserciones debemos correr el código dando la bandera -ea, el siguiente es una corrida del código desde linea de comando.

\begin{verbatim}
macbook-pro-de-felix-calderon-2:Capitulo_4 felix$ java -ea Aserciones
Enter a number between 0 and 10: 11
Exception in thread "main" java.lang.AssertionError: bad number: 11
	at Aserciones.main(Aserciones.java:15)
macbook-pro-de-felix-calderon-2:Capitulo_4 felix$
\end{verbatim}

En el caso de utilizar Netbeans o Eclipse se debe buscar las opciones de la Máquina virtual de Java y dar la bandera -ea

\section{Introducción a Excepciones}

Una excepción es un evento, que se produce durante la ejecución de un programa, que interrumpe el flujo normal de las instrucciones del programa. Así cuando se produce un error dentro de un método, el método crea un objeto y se lo entrega libre al sistema de ejecución. El objeto, llamado un objeto de excepción, contiene información sobre el error, incluyendo su tipo y el estado del programa cuando se produjo el error. Creación de un objeto de excepción y se la entregó al sistema de ejecución, esto llamado lanzamiento de una excepción.

El primer paso en la construcción de un manejador de excepciones es encerrar el código que podría lanzar una excepción dentro de un bloque try. En general, un bloque try tiene el siguiente aspecto:

\begin{verbatim}
try {
    codigo ...
}
catch finaliza bloque . . 
\end{verbatim}

A continuación se muestra un ejemplo donde se puede notar el uso de excepciones. En el ejemplo sin excepciones se asigna una cadena de texto a una variable llamada cadena, note que tiene espacios en blanco lo cual no es un número. 

\begin{verbatim}
public class Excepciones {
    static public void ejemplo_sin_excepciones() {
        int numero;
        String cadena="  1";
        numero = Integer.parseInt(cadena);
    }
    
    static public void ejemplo_con_excepciones() {
        int numero;
        String cadena = "  1";
        try{
            numero = Integer.parseInt(cadena);
        }
        catch(NumberFormatException ex){
            System.out.println("No es un numero, es una cadena de texto.");
        }        
    }

    static public void Division_por_cero() {
        int d, a;
        
        try { 
            d = 0;
            a = 42 / d;
            System.out.println("Esto no se imprimira");
        }
        catch (ArithmeticException e) {// captura el error de division
            System.out.println("Division por cero.");
        }
        
        System.out.println("Termino la ejecucion");
    }    
    
    public static void main(String args[]){
        ejemplo_con_excepciones();
    }
}
\end{verbatim}

Si corremos el primer ejemplo sin excepciones la ejecución se terminará y se produce un mensaje como el siguiente

\begin{verbatim}
Exception in thread "main" java.lang.NumberFormatException: 
   For input string: "  1"
        at java.lang.NumberFormatException.forInputString
          (NumberFormatException.java:48)
        at java.lang.Integer.parseInt(Integer.java:449)
        at java.lang.Integer.parseInt(Integer.java:499)
        at Excepciones.ejemplo_sin_excepciones(Excepciones.java:5)
        at Excepciones.main(Excepciones.java:20)
Java Result: 1
\end{verbatim}

Sin embargo la ejecución del ejemplo con excepciones no terminará la ejecución dando oportunidad de volver al capturar o tomar una acción alterna. La ejecución en este caso es:

\begin{verbatim}
No es un numero, es una cadena de texto.
\end{verbatim}

En el último ejemplo de División por cero, en el caso de que el divisor sea cero el resultado de esta será infinito en cuyo caso el compilador terminará la ejecución con el siguiente mensaje

\begin{verbatim}
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at Excepciones.main(Excepciones.java:37)
Java Result: 1
\end{verbatim}

Con el manejo de excepciones podemos eliminar el problema y sugerir un nuevo dato o captura uno nuevo desde teclado




