2010-06-26 18 views
6

Estoy probando varios ejercicios de un libro de programación de Java. Tengo el siguiente código:Problema con "while" en Java

import java.io.*; 
import java.util.Scanner; 

public class Ex420 
{ 
public static void main(String args[]) 
{ 
    String employeeName = ""; 
    double workHours,excessHours, hourlyRates, grossPay; 
    Scanner input = new Scanner(System.in); 

    while (employeeName != "stop") 
    { 
    System.out.printf("\nInput employee name or stop to exit: "); 
    employeeName = input.nextLine(); 
    System.out.printf("Input working hours: "); 
    workHours = input.nextDouble(); 
    System.out.printf("Input hourly rates: "); 
    hourlyRates = input.nextDouble(); 

    if (workHours <= 40 & workHours >= 0) 
    { 
    excessHours = 0; 
    grossPay = hourlyRates * workHours; 
    System.out.printf("%s's gross pay is $%.2f\n", employeeName, grossPay); 
    } 
    else if (workHours > 40) 
    { 
    excessHours = workHours - 40; 
    grossPay = hourlyRates * 40 + 1.5 * hourlyRates * excessHours; 
    System.out.printf("\n%s's worked for %.1f excess hours.\n", employeeName, excessHours); 
    System.out.printf("%s's gross pay is $%.2f\n", employeeName, grossPay); 
    } 
    else 
    { 
    System.out.printf("Invalid input. Please try again."); 
    } 
    } // end while 
} // end main 
} // end class Ex420 

El problema es que el bucle while no parece funcionar. Cada vez que ingreso "stop" como employeeName, el programa simplemente continúa. Intenté reemplazar "detener" con cualquier otra cadena y todavía no funciona. Pero cuando trato de inicializar employeeName con "stop", el programa se cierra de inmediato, lo que se espera. ¿Qué estoy haciendo mal aquí?

Además, después del primer ciclo, el programa omite siempre preguntar al employeeName. He intentado reemplazar employeeName = input.nextLine(); con employeeName = input.next(); y ya no se lo saltea. Sin embargo, me pregunto, ¿hay alguna manera de que pueda hacerlo, no omitir la entrada al usar employeeName = input.nextLine();?

¡Gracias de antemano por la ayuda!

Respuesta

7

Supongo que es porque la prueba != que utiliza en el ciclo while compara las cadenas para la igualdad de referencia. Es decir, cuando hace una comparación, no es solo probar para ver si las cadenas tienen la misma secuencia de caracteres; comprueba si son exactamente el mismo objeto. Pero cuando el Scanner crea un String para contener el texto que lee de la entrada estándar, ese String no va a ser el mismo objeto que el literal de cadena "stop" en su código. Son dos objetos que simplemente tienen el mismo contenido, pero existen en diferentes lugares de la memoria, por lo que != los trata como desiguales.

Solución: iniciar el bucle de esta forma:

while (!"stop".equals(employeeName)) { 
13

Al comparar cadenas en Java el uso es igual al método, no == o! = Operadores. Al usar esos operadores, simplemente compara referencias a objetos y no a sus contenidos. Por lo que su condición debe ser similar

while (!"stop".equals(employeeName)) 

Nota el que "parada" es en primer lugar porque, teóricamente, la variable de employeeName puede ser nulo. De esta forma, el código no arrojará NullPointerException llamando al método igual en el objeto nulo.

+1

Probablemente quiera decir 'while (!" Stop ".equals (employeeName))' para que coincida con el significado del código de ejemplo, ¿no? – maerics

+0

Me gusta la expresión 'Yoda' :) – VoodooChild

2

El problema es que no está utilizando la estructura correcta y necesita usar equals() no == para comparar String s. La estructura básica que desea es:

System.out.printf("\nInput employee name or stop to exit: "); 
String employeeName = input.nextLine(); 
while (!employeeName.equals("stop")) { 
    ... 
    System.out.printf("\nInput employee name or stop to exit: "); 
    employeeName = input.nextLine(); 
} 

Básicamente es necesario comprobar si el usuario introduce "detener" inmediatamente y lo anterior hace eso. Tu versión no.

Como nota al margen, intente y adopte las convenciones de codificación de Java, incluyendo el espaciado y la colocación de llaves.

+0

¿Por qué el voto a favor? – cletus

+0

¡Gracias por la entrada sobre el ciclo while y las convenciones de programación! No me di cuenta de que mi espaciado y ubicación son diferentes. – bow

0

Ditto críticos anteriores en comparación con == iguales.

Funciona cuando inicializa employeeName para "detener" porque el compilador de Java ve dos cadenas idénticas y reutiliza el objeto. Es decir:

String employeeName = "stop"; if (employeeName == "stop") ... etc ...

La prueba se evalúa como verdadera porque Java crea un objeto para contener la primera cadena, luego nota que la segunda cadena es idéntica por lo que reutiliza el objeto, y por lo tanto la comparación == está comparando un objeto consigo mismo.

Pero si en su lugar lees el employeeName desde el teclado o un archivo, ahora el compilador por supuesto no sabe lo que alguien va a escribir, se crea un nuevo objeto para mantener este valor, y un == comparar entre dos diferentes objetos de cadena devuelve falso.