RSS

Archivos Mensuales: noviembre 2011

Control del Flujo: Bucles

Los bucles nos permiten alterar el flujo de ejecución de un programa ejecutando repetidamente una sentecia o grupo de sentencias.

En Java 6 tenemos tres opciones distintas a la hora de realizar iteraciones:

  • while,
  • do while,
  • for (normal y mejorado)

Vamos a ver cada una de ellas en detalle.


While

Es el bucle indicado cuando no se sabe de antemano cuántas veces se va a ejecutar el bucle. Simplemente queremos que se repitan ciertas acciones mientras la condición del bucle sea cierta.

//inicialización de variables
while (condicion){   //La condicion debe evaluarse a boolean
    //codigo         //Puede no ejecutarse ninguna vez
}

Cómo funciona:

Al entrar en el while se comprueba la condicion por primera vez.
Si resulta falsa no llega a ejecutar el código y se prosigue la ejecución fuera del bucle.
Si es cierta se ejecuta el código y se vuelve a comprobar la condición.
Así sucesivamente hasta que la condición devuelva falso y salgamos del bucle.

Como veremos la última sentencia que se ejecutará en un bucle siempre será la comprobación de la condición.

Por ejemplo:
En este código la variable i vuelve a incrementarse en la última comprobación de la condición del bucle, cuando ésta ya es falsa.

public class EjemWhile1{
    public static void main (String[] args){
        int i = -1;
        boolean encontrado = false;
        int[] medidas = {10, 30, 40, 50, 70};
        while (++i < 5 && !encontrado){
            if(medidas[i] == 40){
             encontrado = true;
            }
        }
        System.out.println(i);
    }
}

En los bucles while estar atento a:

  • Declaración de variables en la condición del while. No se puede, deben estar declaradas con anterioridad.
  • Expresiones en la condición del while que no sean boolean.
    Por ejemplo: enteros en lugar de boolean o asignaciones en lugar de comparaciones, darán error de compilación.


Do While

En estos bucles primero se ejecuta el código y luego se comprueba la condición, por lo que tenemos asegurado que el código se ejecuta al menos una vez.

do{
    elem = pila.obtener();
    System.out.println("elem: " + elem);
} while (!pila.esVacia());

Cómo funciona:
En primer lugar se ejecuta el código del bucle.
A continuación se comprueba la condición. Si esta es falsa se prosigue la ejecución fuera del bucle. Si es verdadera se ejecuta el código y se vuelve a comprobar la condición.

Estar atento a las mismas consideraciones que en el while.


For

Es el bucle que solemos utilizar cuando sabemos cuántas veces queremos ejecutar cierto código.

En su sintaxis podemos destacar tres partes importantes:
– declaración e inicialización de variables
– condición
– incremento.

Aunque ninguna de ellas son obligatorias.

Ejemplo de bucle mínimo for:

for ( ; ; ){ //sin inicializacion, condición ni incremento. Sería un bucle infinito.
    //infinito
}

Ejemplo de un bucle for que equivaldría a un while:(sin inicialización ni incremento)

int i = 0;
for ( ; i<10 ; ){
    i++;
}

Ejemplo de un bucle for típico:

for (int i=0;i<10;i++){
    //declaración e inicializacion "int i=0"
    //condicion "i<10"
    //incremento "i++"
    System.out.println("i: " + i);
}

Cómo funciona:

La inicialización de la variable se ejecuta al principio una sola vez.
A continuación se comprueba la condición y si es falsa se prosigue la ejecución fuera del bucle.
Si resulta cierta se ejecuta el código, se incrementa la variable y se vuelve a comprobar la condición.

Consideraciones del For.

Declaración e inicialización:

  • Se pueden declarar 0, 1 o más variables del mismo tipo. Si hay más de una se separan por comas.
  • Las variables declaradas en el for pierden su ámbito al salir del bucle for.
  • Esta parte sólo se ejecuta una vez, al principio de la ejecución del bucle.

Condición:

  • Sólo se puede comprobar una condición no varias.

Incremento:

  • Se ejecuta despúes de que se ejecute el código del for.


For “Mejorado”

Simplifica recorrer un array o una colección. Tiene dos partes, la declaración y el elemento a recorrer.

int[] array = {10,20,30,50};
for (int elem: array){
    System.out.println("elem: " + elem);
}

En la declaración: hay que declarar una variable compatible con el tipo de los elementos del array o de la colección.

En la expresión: será una variable array, colección o un método que las retorne.

 
Deja un comentario

Publicado por en 30 noviembre, 2011 en Estudio, Tema 5

 

Etiquetas: , , , , , , , ,

Control del Flujo: If y Switch

Las sentencias condicionales permiten ejecutar código de forma selectiva.
En Java tenemos las sentencias condicionales if y switch.

Sentencia If:
La sintaxis más sencilla de una sentencia if es:

if (expresionLogica)  //Si expresionLogica se evalúa a true entonces se ejecuta codigo.
   codigo

Si se tiene una sola sentencia de código no es obligatorio encerrarla entre llaves pero siempre es recomendable por legibilidad.

Ejemplo:

if (precio < 100){
    comprar();  //Mas legible entre llaves.
}

 

Si nos encontramos un if sin llaves debemos recordar que solo aplica a la primera sentencia.

if (precio < 100)
    comprar();      //Solo esta sentencia forma parte del if.
    salirTienda();  //No forma parte del código del if. Siempre se ejecuta.
    volverACasa();  //No forma parte del código del if. Siempre se ejecuta.

La cláusula else es opcional. Se incluye cuando queremos que se ejecute código en el caso de que no se cumpla la condición en el if.

if (precio < 100){
    comprar();
}
else{
    System.out.println("Yo no soy tonto.");
}

También podemos tener una estructura if, else-if, else. Se da en los casos en los que queremos comprobar varias condiciones.

if (precio < 100){
    comprar();
}
else if (price < 2000 && tengoCredito){
    comprarConTarjeta();
}
else{
    System.out.println("Yo no soy tonto.");
}

En las sentencias If se cumplirá:

  • Habrá 0 o muchos else-if y precederán a la cláusula else.
  • Habrá 0 o 1 else e irá a continuación de todas las cláusulas else-if.
  • Cuando una condición se cumple el resto no se comprueba.
  • Si tenemos un else y no sabemos a que if corresponde será el más cercano sin else.
  • La asignación en una condición no da error si se trata de un lógico: if(indicador=true)


Switch

Con esta sentencia vamos a evaluar una expresión y dependiendo de su valor ejecutaremos un código u otro:

switch (expresion){
    case constante1: codigo1
    case constante2: codigo2
    case constante3: codigo3
    default: codigo
}

Si expresion coincide con alguna de las constantes se ejecutará el código de ese case y se seguirá ejecutando el código de los siguientes case hacia abajo hasta que se encuentre una sentencia break.

La sentencia default es opcional y se puede especificar cuando queremos que se ejecute un código para cualquier valor que sea distinto a los especificados en los case.

En los siguientes ejemplos podemos comprobar cómo afecta al resultado la existencia y posición de las sentencias breaks y default:

1. Ejemplo de un Switch Típico.
Switch con breaks en cada case y una clásula default al final.
Recorremos el array niveles. Cada valor entra en su case correspondiente y para al tener la sentencia break. Al estar la cláusula default al final no hace falta que tenga break.

public class EjemploSwitch1{
    public static void main (String[] args){
        int[] niveles = {1, 2, 3, 0};

        System.out.println("\nEjecucion Switch Tipico (breaks y default al final): " );
    	for (int i=0; i < niveles.length; i++){  	{
            System.out.println("Nivel: " + niveles[i]);
    	    switch (niveles[i]){
            case 1:   System.out.println("\tNivel Basico.");
                      break;

            case 2:   System.out.println("\tNivel Intermedio.");
                      break;

            case 3:   System.out.println("\tNivel Avanzado.");
                      break;

            default: System.out.println("\tNivel no informado.");
            }
    	}
    }
}

Resultado:


2. Sentencia Default No al Final.
En este caso hemos colocado la sentencia default sin break después del primer case. Todos los case tienen break. Cuando niveles[i] es igual a 0, ejecuta el código asociado a default. Al no tener break pasa al case 2, ejecuta su código y entonces sí para al tener break.

public class EjemploSwitch2{
    public static void main (String[] args){
        int[] niveles = {1, 2, 3, 0};
	System.out.println("\nEjecucion Switch con Breaks Default enmedio sin break: " );
    	for (int i=0; i < niveles.length; i++)   	{
            System.out.println("Nivel: " + niveles[i]);
    	    switch (niveles[i]){
            case 1:   System.out.println("\tNivel Basico.");
                      break;

            default:  System.out.println("\tNivel no informado.");

            case 2:   System.out.println("\tNivel Intermedio.");
                      break;

            case 3:   System.out.println("\tNivel Avanzado.");
                      break;

            }
    	}
    }
}

Ejecución:


3. Sentencias Case sin Break (Ejemplo en el que no tiene lógica aplicarlo).
En este Switch comprobamos qué ocurre si no colocamos ningún break. Para cada valor de niveles se ejecutan todos los case y default.

public class EjemploSwitch3{
    public static void main (String[] args){
        int[] niveles = {1, 2, 3, 0};
        System.out.println("\nEjecucion Switch sin Breaks (entra en todos los case cada vez): ");
        for (int i=0; i < niveles.length; i++)
        {
            System.out.println("Nivel: " + niveles[i]);
    	    switch (niveles[i])
            {
              case 1: System.out.println("\tNivel Basico.");

              case 2: System.out.println("\tNivel Intermedio.");

              case 3: System.out.println("\tNivel Avanzado.");

              default: System.out.println("\tNivel no informado.");
            }
        }
    }
}

Ejecución:


4. Sentencias Case Sin Break (Ejemplo en el que sí podría ser útil).
En este caso comprobamos cómo a veces puede tener lógica para nuestro código dejar los case sin break. Hemos cambiado el orden de las constantes en los case.

public class EjemploSwitch4{
    public static void main (String[] args){
        int[] niveles = {1, 2, 3, 0};

	System.out.println("\nEjecucion Switch sin Breaks (con logica que podria ser correcta): ");
        for (int i=0; i < niveles.length; i++)
        {
            System.out.println("Nivel: " + niveles[i]);
    	    switch (niveles[i])
            {
              case 3: System.out.println("\tNivel Avanzado.");

              case 2: System.out.println("\tNivel Intermedio.");

              case 1: System.out.println("\tNivel Basico.");
                      break;

              default: System.out.println("\tNivel no informado.");
            }
    	}
    }
}

Ejecución:


En el switch se debe cumplir:

  • La expresión evaluará a char, byte, short, int o enum.
  • Las constantes deben ser constantes en tiempo de compilación.
  • Hay que usar break cuando se necesite parar evitar la ejecución de los case posteriores.
  • La cláusula default no tiene por qué ser la última.
  • No puede haber dos case comprobando el mismo valor. No compilará.
  • No se pueden omitir las cláusulas case ni los ‘:’
 
Deja un comentario

Publicado por en 28 noviembre, 2011 en Estudio, Tema 5

 

Etiquetas: , , , , , , ,

Los Operadores en Java (II)

Operador Resto: %

Devuelve el resto de una división.

class Resto{
    public static void main (String[] args){
        int dividendo = 15;
        int divisor = 2;
        int resto = dividendo % divisor;
        System.out.println("Resto: " + resto);

        int expresion = 3 + dividendo % divisor;
        System.out.println("Expresion: " + expresion);
    }
}

Hay que recordar que los operadores *, /, % tienen una prioridad mayor que los operadores + y -, como se puede comprobar en el ejemplo.

Recordamos también que las expresiones se evalúan por defecto de izquierda a derecha y que para cambiar la prioridad en las evaluaciones se pueden utilizar paréntesis.


Operador Concatenador: +
Con este operador se realiza una concatenación de objetos String y resulta en un nuevo objeto String.

String sujeto = "Ellos";
String predicado = "estudiaban Java";
String frase = sujeto + " " + predicado;
System.out.println(frase); //Devuelve "

Si uno de los argumentos del operador + es String el otro argumento se convierte en objeto String.

Por ejemplo, entre números y String:

class PruebaConcatenador{
    public static void main (String[] args){
        String nombre = "Virginia";
        int a = 10;
        int b = 20;

        System.out.println(nombre + a + b);
        System.out.println(a + b + nombre);
        System.out.println(a + b + nombre + a + b);
    }
}

Devolvería:

Todos los objetos pueden convertirse en objeto String de forma automática, pero el resultado puede tener poco significado. Es por esto que para dar una representación significativa de un objeto en String se suele sobrecargar el método toString().


Operadores de Incremento y Decremento: ++, —
Estos operadores se pueden colocar delante de la variable (notación prefjia) o después de la variable (notación sufija) y realizan un incremento o decremento en 1 en el valor de la variable.

Cuando tenemos la notación prefija (++i ó –i), primero se realiza el aumento o decremento en el valor y luego se evalúa.
Cuando tenemos la notaciión sufija (i++ ó i–), primero se evalúa y luego se realiza el aumento o decremento en el valor.

Por ejemplo:

class OperadoresIncrDecr{
    public static void main (String[] args){
        int a = 10;
        int b = 10;
        System.out.println("a++: " + a++); //1º Evalua con a y luego la incrementa.
        System.out.println("++b: " + ++b); //1º Incrementa y luego evalua con el nuevo valor.

        System.out.println(a); //Comprobamos que el valor se ha incrementado.
        System.out.println(b); //Comprobamos que el valor se ha incrementado.
    }
}

Devuelve:


Operador Condicional: ?:
El siguiente operador evalúa una condición y asigna un valor si es verdadera u otro valor si es falsa.

x = (expresion logica) ? valorSiVerdadero : valorSiFalso

Por ejemplo:

int nota = 80;
String resultado = (nota >= 65)? "Aprobado!!!" : "Suspenso";



Operadores Lógicos: &, |, &&, ||, ^, !

& y | son los operadores And y Or lógicos. Evalúan siempre ambas condiciones. No tienen evaluación perezosa.

&& y || son los operadores And y Or lógicos con evaluación perezosa.
Quiere decir que si pueden dar el resultado evaluando solo la primera condición no evaluarán la segunda.

Esto se da cuando:

  • La primera condición en || es cierta, independientemente de la segunda condición el resultado ya es cierto.
  • La primera condición en && es falsa, independientemente de la segunda condición el resultado es falso.

Un ejemplo con operadores de incremento para comprobar los diferentes resultados que podemos obtener si usamos un operador con evaluación normal o perezosa:

class Logicos{
    public static void main (String[] args){
        int a = 0; //Valores para operadores &, |
        int b = 5;
        int c = 0; //Valores para operadores perezosos &&, ||
        int d = 5;

        if ( a == 0 | b++ > 2) //Evalúa las dos condiciones y b se incrementa.
        {    System.out.println("Cierto (a==0 |  b++ > 2)-> a: " + a + " b: " + b);  }

        if (c == 0 || d++ > 2) //Evalúa solo la 1ª condición al ser cierta (c==0), b no incrementa.
        {    System.out.println("Cierto (c==0 || d++ > 2)-> c: " + c + " d: " + d);  }

        System.out.println();

        if (a > 0 & b++ < 5) //Evalúa las dos condiciones, b se incrementa de nuevo.
        {  }
        else
        {    System.out.println("Falso (a>0 &  b++  a: " + a + " b: " + b);  }

        if (c > 0 && d++ < 5) //Evalúa solo la 1ª condición por ser falsa (c > 0), d no incrementa.
        {    }
        else
        {    System.out.println("Falso (c>0 && d++ <5) -> c: " + c + " d: " + d);  }
    }
}

Devuelve:

^ es el operador Xor. Devueve cierto cuando una de las condiciones es falsa y la otra verdadera.
Siempre evalúa ambos operandos.

! es el operador Not. Si la condición es cierta devuelve falso y si es falsa devuelve cierto.
Con esto terminamos el tema de Operadores.
Recordaros que los operadores de desplazamiento de bits no entran en el examen para la versión 6. Os podéis encontrar preguntas sobre desplazamiento de bits en cuestionarios por ser de versiones anteriores.

En este post tenéis algunos ejercicios resueltos sobre Operadores.

 
6 comentarios

Publicado por en 4 noviembre, 2011 en Tema4

 

Etiquetas: , , , , , , , , ,

Los Operadores en Java (I)

Operadores

Los operadores son símbolos especiales que producen un nuevo valor a partir de uno o varios operandos.
Los valores producidos son, en la mayoría de los casos, booleanos o numéricos.


En la imagen tendríamos un ejemplo de un operador binario, que a partir de dos operandos produciría un nuevo valor.

En la siguiente tabla mostramos los operadores en Java, su orden de precedencia y su asociatividad.
(I-D: de izquierda a derecha, D-I: de derecha a izquierda).



Operador de Asignación: =
Cuando asignamos valor a variables de tipo primitivo hay casos en los que se produce un casting implícito, otros en los que es necesario un casting explícito y casos en los que se puede producir un truncamiento.
Cuando asignamos valores a variables de tipos de referencia debemos tener cuidado con el tipo.

Esto lo podemos ver en los posts del Tema3.



Operadores de Asignación Compuestos: +=, -=, *=, /=
Se tratan en el examen los cuatro anteriores por ser los más usuales.

Algunos ejemplos:

x += 10; //sería igual a  x = x + 10;
y -= 50; //sería igual a  y = y - 50;
z *= 7;  // equivale a  z = z * 7;
w /= 100; // equivale a w = w/100;

En los operadores compuestos la expresión de la derecha siempre se evalúa primero.

x *= 3 + 5; //sería equilvalente a x *= (3+5), es decir x = x * (3 + 5)  y no x = (x * 3) + 5.



Operadores Relacionales: <, <=, >, >=
Siempre devuelven true or false. Se suelen utilizar en sentencias ifs para comprobar condiciones o en expresiones para asignar el valor resultante a una variable boolean.

Pueden comparar cualquier combinación de enteros, reales o carácteres. Cuando se compara con un carácter se utiliza su valor Unicode numérico.

Ejemplos:

boolean resultado;
int x = 200;
if (x<=100)
{
  resultado = true;
}
else
{
  resultado = false;
}

También se podría hacer directamente:

boolean resultado;
resultado = (x<=100);

Con caracteres:

char a = 'A';
char b = 'B';
boolean resultado = a>b;



Operadores de Igualdad: ==, !=

Se pueden comparar dos números, dos carácteres, dos boolean o dos variables de referencia.
Cuando se comparan tipos primitivos devolverá true si ambos valores son iguales.
Cuando se comparan referencias devolverá true si las variables apuntan al mismo objeto.
(No si dos objetos son iguales).

Ejemplos:

class Igualdad{
    public static void main (String[] args)
    {
         int a = 100;
         char b = 'b';
         boolean res = true;

         char[] letras1 = {'a','b','c','d'};
         char[] letras2 = {'a','b','c','d'};

         if (a == 100L)
         { System.out.println("100 y 100L, Iguales");}

         if (res != (b&gt;a))
         { System.out.println("res distinto a (b>;a)");}

         if (letras1 == letras2) //Imprime distinto aunque ambos tengan el mismo contenido.
         { System.out.println("Iguales");} //porque cada referencia apunta a un obj distinto.
         else
         { System.out.println("Distintos");}

         letras2 = letras1; //hacemos que letras2 apunte a letras1

         if (letras1 == letras2) //Imprimirá iguales porque ahora
         { System.out.println("Iguales");} //apuntan al mismo objeto.
         else
         { System.out.println("Distintos");}
    }
}

 


Operador instanceof:

Se utiliza solo con referencias y comprueba si un objeto es de una clase o interfaz determinada.

Por ejemplo, supongamos la siguiente jerarquía de clases:


La clase Persona tiene una subclase Empleado. Empleado a su vez tiene una subclase Tecnico.
Además la clase Persona implementa la interfaz Modales.

Con las siguientes declaraciones:

Persona p1 = new Persona();
Persona p2 = new Empleado();
Empleado e1 = new Empleado();
Tecnico t1 = new Tecnico();
Boolean b;

¿Qué devolvería el operador instanceof en las siguientes líneas de código?

b = p1 is instanceof Persona;
b = p1 is instanceof Modales;
b = p1 is instanceof Object;
b = p1 is instanceof Empleado;
b = p1 is instanceof Tecnico;

b = p2 is instanceof Persona;
b = p2 is instanceof Empleado;
b = p2 is instanceof Modales;
b = p2 is instanceof Tecnico;

b = e1 is instanceof Empleado;
b = e1 is instanceof Modales;
b = e1 is instanceof Persona;
b = e1 is instanceof Tecnico;

b = t1 is instanceof Persona;
b = t1 is instanceof Modales;
b = t1 is instanceof Empleado;
b = t1 is instanceof Tecnico;

b = null is instanceof Persona;
b = e1 is instanceof String;

Seguimos con el resto de operadores en la siguiente entrada…

 
1 comentario

Publicado por en 2 noviembre, 2011 en Tema4

 

Etiquetas: , , , , , , , , ,

 
A %d blogueros les gusta esto: