Ayuda subprogramas Java, array

Hola. Necesito guardar un array para llamarlo desde otros subprogramas, pero no se como, me explico:

Tengo que hacer varios subprogramas tales como rellenar una tabla, mostrar el contenido de la tabla, mostrar la posicion del valor maximo... y demas, pero no se como pasar la tabla una vez rellena del primer subprograma al resto que piden.
El ultimo ejercicio es hacer uno que compruebe que el resto va bien, asi que he realizado un menu, pero solo consigo rellenarla tabla asi:

Un trozo del menu:
public class Lab9 {
    public static void main(String[] args) {
        int opcion;
        opcion = mostrarMenuYLeerOpcion();
        while (opcion != 6) {
            switch (opcion) {
            case 1:
                rellenarTabla();
                break;
            case 2:
                mostrarContenidoTabla();
                break;
            case 3:
                posicionValorMax();
                break;


Subprograma para rellenar la tabla (este subprograma me lo dan, asi que no se deberia de modificar):
public static void rellenarTabla(int tablaNumeros[]) {
        BufferedReader entrada = new BufferedReader(new InputStreamReader(
                System.in));
        try {
            for (int posicion = 0; posicion < tablaNumeros.length; posicion++) {
                System.out.println("Introduce un número");
                tablaNumeros[posicion] = Integer.parseInt(entrada.readLine());
            }
        } catch (IOException ex) {

        } catch (NumberFormatException ex) {

        }
    }


Subprograma para mostrar la tabla:
public static void mostrarContenidoTabla(int tablaNumeros[]) {
        for (int posicion = 0; posicion < tablaNumeros.length; posicion++) {
            System.out.println(tablaNumeros[posicion]);
        }
    }


Subprograma para el 1 del menu:
public static void rellenarTabla() {
        int tablaNumeros[];
        tablaNumeros = new int[10];
        rellenarTabla(tablaNumeros);
    }


Subprograma para el 2:
Como? no se como hacer para coger la tabla ya rellena del primer subrpograma, el de rellenarTabla() para que la muestre (lo de mostrar lo haria con un for).
Tambien podria quitar el menu, pero me gustaria aprender esta otra forma.

¿Alguna idea de como guardar esa tabla para pasarla a los diferentes subprogramas?
Gracias, hasta luego.
FCKU está baneado del subforo por "No especificado"
No te he entendido muy bien, pero si no puedes modificar el trozo de codigo que te dan intuyo que lo que pretenden es que:

1) Te declares un array vacio de 'n' enteros
2) Lo pases por referencia al trozo de codigo que te dan para meterle valores por teclado (puesto que dicha funcion devuelve void)
3) Uses el array ya iniciado para el resto de operaciones (mostrar, obtener el numero mayor, etc)

Cuando desde java invocas metodos con atributos estos se pasan por referencia. Esto es, el objeto es unico, lo que pasas es un puntero al objeto, y si lo modificas en el metodo al que invocas dicho objeto quedara modificado al salir de el.

Hay un ejemplo de lo que comento en el libro "thinking in java", 3a edicion en ingles, en la página 1081 del pdf. Este libro se puede descargar gratuitamente de la web en pdf. Te aconsejo que lo bajes y lo uses como referencia.

Espero haber resuelto tu duda. Un saludo.
No esta hecho lo que me comentas? me explico:
FCKU escribió:No te he entendido muy bien, pero si no puedes modificar el trozo de codigo que te dan intuyo que lo que pretenden es que:

1) Te declares un array vacio de 'n' enteros
2) Lo pases por referencia al trozo de codigo que te dan para meterle valores por teclado (puesto que dicha funcion devuelve void)

public static void rellenarTabla() {
        int tablaNumeros[];
        tablaNumeros = new int[10];
        rellenarTabla(tablaNumeros); //Paso por referencia es esto, ¿no?
    }

Donde pongo lo de paso por referencia, creo que es eso, porque luego en el primer subprograma para ver si la tabla esta rellena la muestro y sale, pero es el punto 3 el que no se como ir pasandolo, a no ser que quite el menu y ejecute uno tras otro, que saldria muy mal, ya que al ejecutarlo despues de meter los n numeros (he puesto 10 porque hay que probarlo), mostraria los diez numeros, luego la posicion del numero maximo... es decir, tardaria mas y queda peor mostrado que

3) Uses el array ya iniciado para el resto de operaciones (mostrar, obtener el numero mayor, etc)

Este es el punto que pregunto.

Cuando desde java invocas metodos con atributos estos se pasan por referencia. Esto es, el objeto es unico, lo que pasas es un puntero al objeto, y si lo modificas en el metodo al que invocas dicho objeto quedara modificado al salir de el.

Por aqui me comentaron que en java no hay punteros (o eso entendi), y no lo he dado, asi que no se que son, de momento.

Estoy mirando esa pagina del libro y es un poco lioso de entender, aparte que opera con private y yo no puedo usar, a ver.
Mas o menos ya esta, pero a ver si alguien me puede ayudar en la pregunta de si eso es paso por referencia y asi.
Gracias, hasta luego.
FCKU está baneado del subforo por "No especificado"
Me esta costando entenderlo pero creo que ya se lo que quieres hacer :). Si me equivoco corrigeme que hoy estoy bastante espeso.

Te pego un trozo de pseudocodigo con cambios:
public class Lab9 {

    private static final int LONGITUD_ARRAY = 10;

    public static void main(String[] args) {

        int opcion;
        int [] arrayEnteros = new int [LONGITUD_ARRAY];

        opcion = mostrarMenuYLeerOpcion();
        while (opcion != 6) {
            switch (opcion) {
            case 1:
                arrayEnteros = rellenarTabla(); // ahi inicias el array de enteros
                break;
            case 2:
                mostrarContenidoTabla(arrayEnteros);
                break;
            case 3:
                posicionValorMax(arrayEnteros);
                break;


Modificamos el método rellenarTabla(). Quiero creer que es tuyo puesto que es distinto al que has dicho que no puedes cambiar.

public static int[] rellenarTabla() {
        int tablaNumeros[] = new int [LONGITUD_ARRAY];
        rellenarTabla(tablaNumeros); //Paso por referencia es esto, ¿no? --> si :)
        return tablaNumeros;
    }


Una vez salgas de ese metodo y vuelvas al switch del main() tendras los valores introducidos por teclado en la variable 'arrayEnteros'. De este modo podras utilizar los casos 2 y 3 con los datos ya iniciados.

Por aqui me comentaron que en java no hay punteros (o eso entendi), y no lo he dado, asi que no se que son, de momento.

Los punteros existen en java, otra cosa es que no los utilices implicitamente. Por eso no te preocupes.

Si te he entendido mal o no has entendido algo pregunta.

Un saludo
FCKU escribió:Cuando desde java invocas metodos con atributos estos se pasan por referencia. Esto es, el objeto es unico, lo que pasas es un puntero al objeto, y si lo modificas en el metodo al que invocas dicho objeto quedara modificado al salir de el.

Realmente no es así.

http://javadude.com/articles/passbyvalue.htm

Sobre tu problema, lo único que tienes que hacer es declarar fuera el array y pasarlo como argumento a los distintos métodos, no necesitas modificar rellenarTabla().

Un saludo.
En la declaración:
public static void rellenarTabla(int tablaNumeros[])

Nos indica que le debemos pasar un array de enteros como parámetro a rellenarTabla.
Así que lo que debes de hacer es declarar el array pasárselo como parámetro al método rellenarTabla.


int arrayNumeros[];
rellenarTabla(arrayNumeros[]);

con esto debería ser suficiente.

Salu2
Bien, ya esta, al final lo hice asi:

public class Lab9 {
    public static void main(String[] args) {
        int opcion;
        int tablaNumeros[];
        tablaNumeros = new int[10]; //Mejor asi o pedir usuario tamaño array?
        opcion = mostrarMenuYLeerOpcion();
        while (opcion != 6) {
            switch (opcion) {
            case 1:
                rellenarTabla(tablaNumeros);
                break;
            case 2:
                mostrarContenidoTabla(tablaNumeros);
                break;
            case 3:
                posicionValorMax(tablaNumeros);
                break;
            case 4:
                mediaValores(tablaNumeros);
                ...


Al final he quitado el metodo "rellenarTabla()".
El problema estaba en que pensaba que el menú tenia que ser asi, ya que asi nos lo habia dado en un laboratorio anterior, pero con lo que habeis puesto aqui me di cuenta de lo del paso por referencia, menu, supongo que se podra cambiar,y listo, hasta funciona y todo. Gracias.


A todo esto, que es mejor de estas dos opciones:

*Crear array diciendole el numero entero:
int tablaNumeros[]
tablaNumeros = new int[10]

*Crear una variable al principio y pasarsela en tablaNumeros (mas o menos como hace FCKU, pero sin lo de private static):
En el metodo principal:
int tablaNumeros[]
final int LONGITUD_ARRAY = 10
tablaNumeros = new int[LONGITUD_ARRAY]

Aunque igual depende del programa, que seria mas correcto? Gracias nuevamente.
bastian escribió:cita de FCKU:
Cuando desde java invocas metodos con atributos estos se pasan por referencia. Esto es, el objeto es unico, lo que pasas es un puntero al objeto, y si lo modificas en el metodo al que invocas dicho objeto quedara modificado al salir de el.

Realmente no es así.

http://javadude.com/articles/passbyvalue.htm


Hombre, es la discusión de siempre. Claro que pasas todo por valor. Cuando pasas un puntero, el puntero lo pasas por valor, pero implicitamente, pasas la variable u objeto a la que apunta por referencia, ya que el puntero es una referencia por definicion.

Salu2!
Dagaren escribió:Hombre, es la discusión de siempre. Claro que pasas todo por valor. Cuando pasas un puntero, el puntero lo pasas por valor, pero implicitamente, pasas la variable u objeto a la que apunta por referencia, ya que el puntero es una referencia por definicion.

Puse ese enlace porque el comportamiento no es el mismo que en C, en el que si pasas un puntero puedes modificarlo (como en el típico ejemplo de la función swap(&a,&b). En Java no, porque pasas una referencia al objeto por valor, es decir OTRA referencia al objeto, distinta de la referencia original. Por tanto si modificas esa referencia en la función, los cambios no se ven reflejados fuera de ella.

Un saludo.
bastian escribió:Puse ese enlace porque el comportamiento no es el mismo que en C, en el que si pasas un puntero puedes modificarlo (como en el típico ejemplo de la función swap(&a,&b). En Java no, porque pasas una referencia al objeto por valor, es decir OTRA referencia al objeto, distinta de la referencia original. Por tanto si modificas esa referencia en la función, los cambios no se ven reflejados fuera de ella.


¿Comorrr? El comportamiento es el mismo, si tu pasas la direccion de una variable en c (un puntero) el puntero aunque lo modifiques dentro de la funcion, no se ve reflejado fuera, lo que puedes modificar y que se vea es el valor de lo que apunta el puntero, y en java igual, no puedes cambiar el objeto al que apunta, pero si puedes cambiar la información del objeto. La única diferencia es que en uno tienes que pensar en variables y en otro en objetos, pero el comportamiento es exactamente el mismo. Otra cosa es que ya andes con punteros a punteros.

Salu2!
FCKU está baneado del subforo por "No especificado"
bastian escribió:Realmente no es así.

http://javadude.com/articles/passbyvalue.htm

Gracias por el apunte. Es bueno saberlo.
Aunque igual depende del programa, que seria mas correcto? Gracias nuevamente.

Hombre, pues depende. Si en varios sitios de tu codigo pones a pelo que la longitud es 10 y por alguna razon en algun momento tienes que cambiarlo a 20 ... ¿no seria mejor tener declarada una constante y que solo tengas que cambiar el valor en un único sitio de todo el codigo?. Imagina que tienes ese '10' en 20 o 30 lugares distintos de tu codigo, yo con mi memoria de pez seria incapaz de recordar donde estan, imaginate si tiene que cambiarlo otra persona, y ademas a la hora de ejecutar el codigo posiblemente apareciesen problemas derivados de querer recorrer las 20 posiciones de un array de 10 y cosas asi :)

Todo esto que comento es tomando como base que en tiempo de compilacion vas a saber exactamente la longitud del array. Por ejemplo, en un equipo de futbol el numero de jugadores siempre va a ser 11, asi que crear una constante con valor 11 no estaria de mas (por cierto, que ganas de que empiece la javacup :-D) puesto que el uso de constantes ayuda a la modificacion y legibilidad del codigo.

Ahora bien, si vas a conocer el numero de elementos en tiempo de ejecucion, por ejemplo porque haya que introducir la longitud por teclado o leerla de un fichero, usar una constante es bastante poco útil, una variable y arreando :-)
Gracias a todos por todo, ahora ya "domino" un poco el tema de los arrays (ahora entro con las listas ligadas...)

Pero me surge una pequeña duda, esta es mas simple (no es resolver nada, es una pregunta al final).

En un laboratorio el profesor nos da esto:
package laboratorio10;
public class TipoAlumno
{
       public int dni;
       public String nombre;
       public String apellido;
}


Y pide definir uno llamado tipoDireccion, que yo lo he hecho asi, con lo que el pide:
package laboratorio10;
public class TipoDireccion {
    public String calle;
    public int numero;
    public int codigoPostal;
    public String localidad;
    public String pais;
}


El caso es que pide que se modifique tipoAlumno para que guarde la direccion del alumno, entonces he pensado en lo siguiente:
package laboratorio10;
public class TipoAlumno
{
       public int dni; //¿Porque public? En transparencias no lo indica como  public
       public String nombre;
       public String apellido;
       TipoDireccion prueba = new TipoDireccion();
}

El caso es que no se si con esa linea al crear un nuevo alumno me creara el TipoDireccion por cada uno creado. ¿seria asi?
Lo digo porque en los apuntes esta para crear dandole un nombre (TipoDireccion prueba) y luego con un new (prueba = new TipoDireccion()) pero aparte de no dar error, debe ser una burrada hacer un registro con un nombre especifico dentro de otro registro.

Bueno, si, una pregunta de como proceder.
Me pide que modifique un programa que el da, rellenando una tabla, para que albergue aparte la direccion. El problema es que no se como referenciar¿?(no se si referenciar es correcto) por ejemplo la calle.
El pone, por ejemplo, para el nombre : tabla[i].nombre = entrada.readLine();
Entonces, ¿como seria para rellenar, por ejemplo, la calle?

Os lo pregunto porque mirando en los apuntes no viene nada de operaciones entre dos registros.
Gracias, hasta luego.
FCKU está baneado del subforo por "No especificado"
Inventado escribió:El caso es que no se si con esa linea al crear un nuevo alumno me creara el TipoDireccion por cada uno creado. ¿seria asi?

Si, ahora cada alumno tiene nombre, apellido, dni y direccion.

Inventado escribió:Lo digo porque en los apuntes esta para crear dandole un nombre (TipoDireccion prueba) y luego con un new (prueba = new TipoDireccion()) pero aparte de no dar error, debe ser una burrada hacer un registro con un nombre especifico dentro de otro registro.

¿? No he entendido a lo que te refieres con "hacer un registro con un nombre especifico dentro de otro registro"

package laboratorio10;
public class TipoAlumno
{
       public int dni; //¿Porque public? En transparencias no lo indica como  public
       public String nombre;
       public String apellido;
       TipoDireccion prueba = new TipoDireccion();
}

es lo mismo que poner el new en el constructor. Personalmente me gusta mas inicializar en los constructores
package laboratorio10;
public class TipoAlumno
{
       [...]
       public TipoDireccion prueba;

        public TipoAlumno() {
             prueba = new TipoDireccion();
        }
}

Por otro lado el atributo dni es "public" para que se pueda acceder desde fuera de la clase a ella. Se carga el concepto de "encapsulamiento" pero estais aprendiendo :)


El problema es que no se como referenciar¿?(no se si referenciar es correcto) por ejemplo la calle.
El pone, por ejemplo, para el nombre : tabla[i].nombre = entrada.readLine();
Entonces, ¿como seria para rellenar, por ejemplo, la calle?

alumno1.prueba.calle = "calle de la direccion del alumno 1"

Mirate el libro que te puse varios comentarios atrás.

Un saludo
FCKU escribió:¿? No he entendido a lo que te refieres con "hacer un registro con un nombre especifico dentro de otro registro"

Si, me refiero a algo como esto:
package laboratorio10;
public class TipoAlumno { //Esto es un registro
       public int dni; //¿Porque public? En transparencias no lo indica como  public
       public String nombre;
       public String apellido;
       TipoDireccion prueba;
       prueba = new TipoDireccion(); //Esto crearia el registro TipoDireccion con el nombre "prueba" dentro del registro TipoAlumno.
}

FCKU escribió:]
alumno1.prueba.calle = "calle de la direccion del alumno 1"

Mirate el libro que te puse varios comentarios atrás.

Un saludo

Supongo que seria algo como:
tabla[i].prueba.calle = entrada.readLine()
Aunque ya mirare el libro, el problema es el inglés, pero es igual.

De todos modos lo de los constructores se dan un par de laboratorios mas tarde, incluso en otro tema mas adelante.
Gracias por todo.
13 respuestas