Problemilla en Java

Kr4n3oK

Hola estoy haciendo un ejercicio en Java, el cual me pide hacer una clase Buzón y otra Correo, bien en un Buzón puede haber correos.
Esto está todo desarrollado era por poneros en situación:

Bueno resulta que en la interfaz de Buzon tengo un método que me devuelve el primer correo sin leer:

public String muestraPrimerNoLeido() {
        boolean encontrado = false;
        int i;
        String texto = null;
        for (i = 0; i <= correos.length - 1; i++) {

     boolean estado = correos[i].getEstado();
        if (estado == false && encontrado = false) {
            encontrado = true;
            correos[i].setEstado(true);
            texto = correos[i].getTexto();
        }
    }

    return texto;

}

Aquí recorro el array de objetos correo y obtengo con el método getEstado true o false.
Ahora, si estado es false, quiere decir que el primer correo no está leido, entonces se cumple la primera condición del if.
Como solo quiero leer el primero necesito un semaforo que me avise cuando se ha leido el primer correo no leido.

El problema reside en que la linea

 boolean estado = correos[i].getEstado();

Me da un NullPointerException, que puede estar pasando?

Gracias

K0N1G

inicializaste correos¿¿

Correo correos[] = new Correos[N]

1 respuesta
Kr4n3oK

#2 Por supuesto xd

Este es el método que añade un correo nuevo:

public void añade(correo c) {
        correos[a] = c;
        a++;

}
1 respuesta
elkaoD

#3 pero usa un ArrayList hijo mío.

Te da un NullPointerException porque el correo no está inicializado (no hay objeto Correo, por tanto no hay método al que llamar. Las posiciones del array están por defecto a null hasta que las inicializas.

Comprueba antes si correo[ i ] es null y, si es así, obvialo. correos.length te da la longitud del array estático, aunque sus elementos no estén inicializados. Si no quieres comprobar null debes llevar tú la cuenta de cuántos hay inicializados (con un atributo externo que aumente y disminuya al añadir y quitar correos.)

1 2 respuestas
Kr4n3oK

#4 Nos lo piden así xddd
#6 Para comprobar que la incialización meti en un System.out..un correos[1].getTexto(), lo saca.

1 respuesta
elkaoD

#5 pues qué cagada. Edité #4 con tu solución.

#5 claro que te saca el 1, porque el 1 está inicializado ¬¬ Mételo en el i, ya verás como excepciona también.

Que correo[1] esté inicializado no significa que lo esté correo[2]. No es lo mismo inicializar un array que inicializar su contenido. El contenido se inicializa de uno en uno y por separado. Tu código sólo puede funcionar si está el array completo incializado. En el momento en el que en alguna posición no haya un correo, boom, NullPE.

Steppea con el debugger y verás que tengo razón.

Por cierto, mejor que <= length-1, haz simplemente < length.

1 respuesta
Kr4n3oK

Ya te pillao xdd, osea, si ahora mismo hay dos correos, el excepto no me lo lanza por esos dos, si no por el resto del array que aún no tiene un objeto inicializado, verdad?

1 respuesta
DaRk-eXe

la solución es la que te ha dicho #4 , de todas formas.. como apunte personal, me da un poco de grima ver un array correo, usa un iterador, es mas elegante y bonito, pero eso ya son pijerías y:

boolean estado = correos[i].getEstado();
            if (estado == false && encontrado = false) {

puedes cambiarlo por, no hace falta usar una variable boolean cuando puedes comprobarlo directamente en el if.

 if (!correos[i].getEstado() && encontrado = false) {

el comando code suda de mi culo. xD

#9 cierto.. me cegué con el getEstado xD

2 respuestas
elkaoD

#7 sipe. Peta en cuanto encuentra un correo null. Joder, si es que lo dice la excepción: NullPointerException xD

#8 de hecho:

if (!correos[i].getEstado() && !encontrado)

El code te peta porque tienes un [ i ] sin cerrar. Y dirás, si yo no he puesto [ i ], pero en realidad lo has puesto en algún correo[ i ] seguro xD Justo te pasa donde pone "array correo". Fíjate que hay que ponerlo separado de los corchetes o lo entiende como un tag. A mí me ha pasado lo mismo.

1 1 respuesta
Kr4n3oK

#8 Sabía que alguien me iba a decir eso xd, eso lo tengo así por que hize un cambio a ver si solucionaba el tema.

PD: Joder que mal se escribe en la cama xdd

Kr4n3oK

Bueno, no sé si sera muy ortodoxo pero lo solucioné tal que así:

if (correos[i] != null) {
                if (!correos[i].getEstado() && !encontrado) {
                    encontrado = true;
                    correos[i].setEstado(true);
                    texto = correos[i].getTexto();
                }
            }
1 respuesta
elkaoD

#11 no, no es ortodoxo. Lo mejor es que lleves la cuenta tú mismo al insertar/eliminar y no hagas el bucle completo.

2 respuestas
Kr4n3oK

#12 No entiendo xd

Kr4n3oK

Así se ha quedado, creo que bastante mejor:

//Muestra el primer no leido
    public String muestraPrimerNoLeido() {

    boolean encontrado = false;
    String texto = null;
    //Recorremos el vector correos
    for (int i = 0; i < a; i++) {
        //Si contiene algo esa posición, comprobamos que esté en false y que ademas el boolean encontrado este false también

        if (!correos[i].getEstado() && !encontrado) {
            encontrado = true;
            correos[i].setEstado(true);
            texto = correos[i].getTexto();
        }

    }

    return texto;

}
1 respuesta
Igneus

#12 xacto, lo logico es que uses un atributo que lleve la cuenta de los objetos que tiene el array y asi no tienes que comprobar si hay objeto o no, y te ahorraras iteraciones en los bucles.

elkaoD

#14 ¿a? Usa nombres descriptivos.

Ahora, lo del "encontrado" es una chapuceada tenerlo dentro del if. Mételo en la condición del for o usa un while. Si no, aunque encuentres vas a recorrer el bucle tontamente. Otra opción sería usar break, pero es casi más chapuzas.

Otra opción es hacer un "return texto" en cuanto lo encuentras. Habrá gente que no le guste, pero yo la programación estructurada me la paso por el forro (excepto breaks/gotos que sí son chapuza total.) IMHO en un método largo pues sí pueden confundir returns en mitad del código, pero sin embargo me parece que a veces meter el return a capón no sólo no empeora las cosas sino que ganas en claridad (y evitas mierda como usar la variable "encontrado" y sus correspondientes checks innecesarios.)

Por lo demás, todo perfecto.

B

Un fallo recurrente en muchas facultades e institutos donde imparten algo relacionado con el desarrollo software es que suelen haceros/nos programar en castellano.

A mí, personalmente, se me antoja imprescindible programar en inglés (tanto variables como comentarios).

Y, como dice KaoD, variables tipo "a" son una aberración por normal general.

Mucho ánimo, ya verás como cuando lleves algo de tiempo este tipo de cosas te dan la risa y te lo pasas genial haciendo tonterías.

1
Fr4nk0

No he dicho nada xD Mi "consejo" ya lo habían dicho antes. Eso pasa por leer rápido xD

1 respuesta
Kr4n3oK

#18 Por mi, comenta, abierto a cualquier cosa estoy, por mínimo que sea.

Fr4nk0

Era usar while con condicion para no hacer iteraciones de más, o usar break o return cuando encuentras el elemento al usar for.

Lo que habían dicho antes vamos :P

2 respuestas
tOWERR

Comparto la opinión de #20, si cuando encuentres un correo no leído tienes que mandarlo no tienes porque recorrer todo el array. Utiliza un while.

elkaoD

Yo también comparto la opinión de #20.

Usuarios habituales