Java - Comparar char

 
Vista:
sin imagen de perfil

Comparar char

Publicado por Xavi (14 intervenciones) el 10/10/2021 15:03:01
Hola,

Estoy creando un setter que evalue el parámetro de entrada "sexo". En este sentido, si el parámetro de entrada no es 'm', 'f', 'M' o 'F' tiene que devolver un error. En caso contrario devuelve siempre el sexo en minúscula.

Hasta el moment he hecho lo siguiente:

1
2
3
4
5
6
7
public void setGender(char gender){
        if (gender!='f' || gender!='m' || gender !=Character.toUpperCase('f') || gender!= Character.toUpperCase('m')) {
            System.out.println("[ERROR] Athlete's gender must be 'f','F','m' or 'M'");
        }else{
            this.gender = Character.toLowerCase(gender);
        }
    }

Sin embargo, estoy obteniendo el siguiente warning:

1
Condition 'gender!='f' || gender!='m' || gender !=Character.toUpperCase('f') || gender!= Character.toUpperCase(...' is always 'true'

Cuál es la razón?

Gracias
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Comparar char

Publicado por Kabuto (1082 intervenciones) el 10/10/2021 20:33:37
Lo que ocurre es que esa expresión SIEMPRE va a ser cierta.
¿Cómo es posible?

Mira, vamos a suponer que le enviamos el carácter 'f' para evaluar la expresión.
En teoría, ese carácter debería ser admitido y establecerse para el gender. Pero es posible que la lógica de la expresión que has desarrollado no sea la idónea.

Vamos a comprobarlo
La primera comparación es:
1
gender!='f'

Es decir, estaríamos preguntando si 'f' es distinto de 'f'
La respuesta es FALSE, porque no son distintos.

Pero la expresión no ha terminado, tiene más comparaciones para realizar.

Y ahora viene esta:
1
gender!='m'
Es decir, preguntamos si 'f' es distinto de 'm'.
La respuesta es TRUE, y con esto ya es suficiente para considerar toda la expresión completa como VERDADERA

Como todas estas comparaciones están unidas por el operador OR, significa que basta con que solo una de ellas sea TRUE para ser considerada cierta.
No importa que la primera comparación nos halla dado un FALSE, como la siguiente nos da TRUE, ya toda la expresión es considerada TRUE

Recuerda:
FALSE or TRUE or FALSE or FALSE --> Es TRUE

Por tanto, la expresión que has construido SIEMPRE será TRUE. Porque da igual el carácter que enviemos para evaluar, SIEMPRE será distinto de alguno, o de todos, de los caracteres con los que comparas.


No se si he conseguido explicarme bien, las expresiones booleanas siempre cuesta un poco entenderlas bien, a pesar de que son pura lógica básica.
Por suerte el compilador lo sabe detectar y te avisa. Porque en realidad no es un error de sintaxis, el programa podría funcionar perfectamente. Pero es un error de lógica, hemos construido una expresión que SIEMPRE va a retornar true, así que el compilador sabe que esa expresión probablemente no va a resultar útil en ningún programa, y por ello te avisa.

Bueno, ¿y cómo corregimos la expresión para que cumpla lo que deseas?
Pues en lugar de usar OR, hay que usar AND.

De ese modo, si se recibe un carácter que es distinto de 'f' Y es distinto de 'm' y es distinto de 'F' y es distinto de 'M'..... pues lo rechazaremos.
Solo se aceptará si NO es distinto de ALGUNO de esos cuatro caracteres.

1
2
3
4
5
6
7
public void setGender(char gender){
        if (gender!='f' && gender!='m' && gender != 'F' && gender!= 'M') {
            System.out.println("[ERROR] Athlete's gender must be 'f','F','m' or 'M'");
        }else{
            this.gender = Character.toLowerCase(gender);
        }
    }


Por cierto, usando el método contains() de la clase String, puede simplificarse la expresión, si construimos un String con todos los caracteres que consideramos válidos.

1
2
3
4
5
6
7
public void setGender(char gender){
        if ("fFmM".contains(Character.toString(gender))) {
            this.gender = Character.toLowerCase(gender);
        }else{
            System.out.println("[ERROR] Athlete's gender must be 'f','F','m' or 'M'");
        }
    }
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar