Listado completo de tutoriales

63 - Estructura repetitiva 'for' adaptada para recorrer colecciones


En los primeros conceptos de este curso vimos como trabaja la estructura repetitiva for.

estructura repetitiva for

En su forma más típica y básica, esta estructura requiere una variable entera que cumple la función de un CONTADOR de vueltas. En la sección indicada como "inicialización contador", se suele colocar el nombre de la variable que hará de contador, asignándole a dicha variable un valor inicial. En la sección de "condición" se coloca la condición que deberá ser verdadera para que el ciclo continúe (en caso de un falso, el ciclo se detendrá). Y finalmente, en la sección de "incremento contador" se coloca una instrucción que permite modificar el valor de la variable que hace de contador (para permitir que alguna vez la condición sea falsa)

Cuando tenemos que iterar por los elementos de una colección (hasta ahora hemos visto los arreglos) accedemos a los mismos por medio de un subíndice que normalmente corresponde al contador de un for:


public class SueldoEmpleados {

    public static void main(String[] args) {
        int []sueldos= {2000, 6000, 7000, 4300};
        for(int f=0;f<sueldos.length;f++)
            System.out.println("Sueldo: "+sueldos[f]);
        int gastos=0;
        for(int f=0;f<sueldos.length;f++) 
            gastos+=sueldos[f];
        System.out.println("Gasto total en sueldos de la empresa: "+gastos);
    }

}

Definimos un vector llamado sueldos y lo inicializamos con 4 elementos:

        int []sueldos= {2000, 6000, 7000, 4300};

Como hemos visto en conceptos anteriores para mostrar los valores almacenados y sumarlos debemos acceder a cada elemento por medio de un subíndice:

        for(int f=0;f<sueldos.length;f++)
            System.out.println("Sueldo: "+sueldos[f]);
        int gastos=0;
        for(int f=0;f<sueldos.length;f++) 
            gastos+=sueldos[f];

Java introduce una variante de la estructura repetitiva for que nos permite iterar por cada elemento del arreglo con la siguiente sintaxis:


public class SueldoEmpleados2 {

    public static void main(String[] args) {
        int[] sueldos = { 2000, 6000, 7000, 4300 };
        for (int monto : sueldos)
            System.out.println("Sueldo: " + monto);
        int gastos = 0;
        for (int monto : sueldos)
            gastos += monto;
        System.out.println("Gasto total en sueldos de la empresa: " + gastos);
    }

}

Si bien se utiliza la misma palabra clave 'for', su contenido es muy distinto (tiene un solo argumento):

        for (int monto : sueldos)
            System.out.println("Sueldo: " + monto);

Previo a los dos puntos definimos una variable del mismo tipo de datos que los elementos del arreglo 'int monto' y luego de los dos puntos indicamos el nombre del arreglo a recorrer.

La variable 'monto' almacena en cada iteración del for un sueldo del arreglo 'sueldos'.

Es decir que la primera vuelta del for la variable 'monto' tiene almacenado el número '2000', la segunda iteración tiene el valor '6000' y así sucesivamente.

En ningún momento accedemos a los elementos del arreglo por medio de un subíndice.

Esta estructura repetitiva no remplaza a la otra estructura for debido que hay muchos casos donde no podemos resolverla con ésta, por ejemplo no podemos modificar los elementos del arreglo dentro del for, ni saber el índice de la componente accedida.

La sintaxis es mucho más legible que el for clásico y su uso es adecuando cuando debemos consultar todos los elementos de una colección.

Problema

Se desea almacenar los sueldos de operarios. Cuando se ejecuta el programa se debe pedir la cantidad de sueldos a ingresar. Luego crear un arreglo con dicho tamaño.
Imprimir todos los sueldos ingresados y mostrar el mayor de ellos.

Programa:

import java.util.Scanner;

public class SueldoEmpleados3 {
    private Scanner teclado;
    private int[] sueldos;

    public SueldoEmpleados3() {
        teclado = new Scanner(System.in);
        System.out.print("Cuantos sueldos cargará:");
        int cant;
        cant = teclado.nextInt();
        sueldos = new int[cant];
        for (int f = 0; f < sueldos.length; f++) {
            System.out.print("Ingrese sueldo:");
            sueldos[f] = teclado.nextInt();
        }
    }

    public void imprimir() {
        for (int sueldo : sueldos)
            System.out.println(sueldo);

    }

    public void sueldoMayor() {
        int mayor = sueldos[0];
        for (int sueldo : sueldos)
            if (sueldo > mayor)
                mayor = sueldo;
        System.out.println("El sueldo mayor que paga la empresa es " + mayor);
    }

    public static void main(String[] ar) {
        SueldoEmpleados3 se = new SueldoEmpleados3();
        se.imprimir();
        se.sueldoMayor();
    }
}

Como vemos la carga del vector requiere un 'for' clásico para poder modificar los elementos del arreglo accediéndolos mediante su subíndice:

        for (int f = 0; f < sueldos.length; f++) {
            System.out.print("Ingrese sueldo:");
            sueldos[f] = teclado.nextInt();
        }

En cambio para imprimir todos los elementos del arreglo y recuperar el mayor elementos podemos utilizar la nueva sintaxis de for:

    public void imprimir() {
        for (int sueldo : sueldos)
            System.out.println(sueldo);

    }

    public void sueldoMayor() {
        int mayor = sueldos[0];
        for (int sueldo : sueldos)
            if (sueldo > mayor)
                mayor = sueldo;
        System.out.println("El sueldo mayor que paga la empresa es " + mayor);
    }

Recorrer una matriz

También podemos utilizar la nueva sintaxis para recorrer una arreglo de dos dimensiones.

Problema

Crear una matriz de n * m filas (cargar n y m por teclado) Imprimir la matriz completa utilizando la estructura for que recorre colecciones.

Programa:

import java.util.Scanner;

public class PruebaMatriz1 {
    private Scanner teclado;
    private int[][] mat;

    public PruebaMatriz1() {
        teclado = new Scanner(System.in);
        System.out.print("Cuantas fila tiene la matriz:");
        int filas = teclado.nextInt();
        System.out.print("Cuantas columnas tiene la matriz:");
        int columnas = teclado.nextInt();
        mat = new int[filas][columnas];
        for (int f = 0; f < mat.length; f++) {
            for (int c = 0; c < mat[f].length; c++) {
                System.out.print("Ingrese componente:");
                mat[f][c] = teclado.nextInt();
            }
        }
    }

    public void imprimir() {
        for (int[] fila : mat) {
            for (int elemento : fila)
                System.out.print(elemento + " ");
            System.out.println();
        }
    }

    public static void main(String[] ar) {
        PruebaMatriz1 pm = new PruebaMatriz1();
        pm.imprimir();
    }
}

La carga de la matriz no se puede hacer con la nueva sintaxis del for, recordar que solo nos sirve para recorrer la colección.

La impresión de la matriz utilizamos dos for anidados con la nueva sintaxis:

    public void imprimir() {
        for (int[] fila : mat) {
            for (int elemento : fila)
                System.out.print(elemento + " ");
            System.out.println();
        }
    }

La variable 'fila' es un vector que almacena en cada iteración una fila de la matriz 'mat':

        for (int[] fila : mat) {

Luego el for interno itera el vector 'fila' y almacena en la variable 'elemento' cada uno de los valores enteros del vector 'fila':

            for (int elemento : fila)
                System.out.print(elemento + " ");
            System.out.println();
        }

Recorrer un arreglo con elementos de tipo objeto.

Problema

Crear un proyecto y dentro del mismo crear dos clases. La primer clase se debe llamar 'Carta' y definir los atributos palo y numero. Por otro lado declarar una clase llamada 'Mazo' que contenga un arreglo de 6 elementos de tipo 'Carta'.
Imprimir todas las cartas. Imprimir una carta al azar entre las 6 cartas.

Programa:

public class Carta {
    private int numero;
    private String palo;

    Carta(int numero, String palo) {
        this.numero = numero;
        this.palo = palo;
    }

    public void imprimir() {
        System.out.println(numero + " - " + palo);
    }

}
public class Mazo {
    private Carta []cartas;
    
    Mazo() {
        cartas=new Carta[6];
        cartas[0]= new Carta(1,"Trebol");
        cartas[1]= new Carta(2,"Trebol");
        cartas[2]= new Carta(3,"Trebol");
        cartas[3]= new Carta(4,"Trebol");
        cartas[4]= new Carta(5,"Trebol");
        cartas[5]= new Carta(6,"Trebol");
    }
    
    public void imprimir() {
        System.out.println("Listado completo del mazo de cartas");
        for(Carta carta: cartas)
            carta.imprimir();
    }
    
    public void imprimirUnaAlAzar() {
        System.out.println("Una carta elegida al azar");        
        cartas[(int)(Math.random()*6)].imprimir();
    }
    
    
    public static void main(String[] ar) {
        Mazo mazo=new Mazo();
        mazo.imprimir();
        mazo.imprimirUnaAlAzar();;
    }
    
}

La ejecución del proyecto genera una salida similar a:

java for colecciones de objetos

En el método imprimir de la clase 'Mazo' hemos utilizado el for alternativo para recorrer el arreglo:

    public void imprimir() {
        System.out.println("Listado completo del mazo de cartas");
        for(Carta carta: cartas)
            carta.imprimir();
    }

En cada iteración del for la variable 'carta' almacena un elemento del arreglo 'cartas'.


Retornar