There is no difference in bytecode between while(true) and for(;;) but I prefer while(true) since it is less confusing (especially for someone new to Java).
You can check it with this code example
void test1(){
for (;;){
System.out.println("hello");
}
}
void test2(){
while(true){
System.out.println("world");
}
}
When you use command javap -c ClassWithThoseMethods you will get
void test1();
Code:
0: getstatic #15 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #21 // String hello
5: invokevirtual #23 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: goto 0
void test2();
Code:
0: getstatic #15 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #31 // String world
5: invokevirtual #23 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: goto 0
which shows same structure (except "hello" vs "world" strings) .
Answer from Pshemo on Stack OverflowJava: Infinite Loop Convention - Stack Overflow
halting problem - Infinite loops in Java - Stack Overflow
Infinite While Loop in Java - Stack Overflow
Having issues with infinite loops in Java
How can I terminate or break out of an infinite loop in Java?
What problems can arise from infinite loops in a Java program?
How can I handle intentional infinite loops to prevent unwanted consequences?
Videos
There is no difference in bytecode between while(true) and for(;;) but I prefer while(true) since it is less confusing (especially for someone new to Java).
You can check it with this code example
void test1(){
for (;;){
System.out.println("hello");
}
}
void test2(){
while(true){
System.out.println("world");
}
}
When you use command javap -c ClassWithThoseMethods you will get
void test1();
Code:
0: getstatic #15 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #21 // String hello
5: invokevirtual #23 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: goto 0
void test2();
Code:
0: getstatic #15 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #31 // String world
5: invokevirtual #23 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: goto 0
which shows same structure (except "hello" vs "world" strings) .
I prefer while(true), because I use while loops less often than for loops. For loops have better uses and while(true) is much cleaner and easy to read than for(;;)
The compiler can easily and unequivocally prove that the first expression always results in an infinite loop, but it's not as easy for the second. In your toy example it's simple, but what if:
- the variable's contents were read from a file?
- the variable wasn't local and could be modified by another thread?
- the variable relied on some user input?
The compiler is clearly not checking for your simpler case because it's forgoing that road altogether. Why? Because it's much harder forbidden by the spec. See section 14.21:
- http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21-300-M
(By the way, my compiler does complain when the variable is declared final.)
According the specifications, the following is said about while statements.
A while statement can complete normally iff at least one of the following is true:
- The while statement is reachable and the condition expression is not a constant expression with value true.
- There is a reachable break statement that exits the while statement.\
So, the compiler will only say that the code following a while statement is unreachable if the while condition is a constant with a true value, or there is a break statement within the while. In the second case, since the value of b is not a constant, it doesn't consider the code following it to be unreachable. There's a whole lot more information behind that link to give you more details on just what is and what isn't considered unreachable.
You don't have an input = keyboard.nextLine(); in your second while loop.
You could refactor your code to only ask for new input when there is an error. So right after the sysout of 'ERROR...'
Extra: I would actually do this different. The 'error = true' at the beginning is a bit confusing, because there might not be an error.
You could for example write a method called tryProcessLine, which reads the input and returns true if ok and false if there was an error, and than just do something like while(!tryProcessLine()){ }
Working example below:
import java.io.IOException;
import java.util.Scanner;
public class Methods {
private static int qoh;
public static void main(String args[]) throws IOException {
while (!tryProcessLine()) {
System.out.println("error... Trying again");
}
System.out.println("succeeded! Result: " + qoh);
}
public static boolean tryProcessLine() {
String input = "";
Scanner keyboard = new Scanner(System.in);
System.out.print("\nEnter Quantity on Hand: ");
input = keyboard.nextLine();
try {
qoh = Integer.valueOf(input);
if (qoh < 0 || qoh > 500) {
System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
return false;
} else {
return true;
}
} catch (NumberFormatException e) {
System.out.println("\n**ERROR06** - Quantity on hand must be numeric");
return false;
}
}
}
The problem is in this section:
while (error==true)
{
if (Character.isLetter(input.charAt(0)))
{
System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
error=true;
System.out.println(qoh);
System.out.println(input);
}
else
{
qoh = Integer.parseInt(input);
error=false;
}
}
Once you have a letter in the first position, this loop can never terminate. It checks whether a letter is in the first position (it is), prints it, and repeats. Try changing to:
while (error==true)
{
if (Character.isLetter(input.charAt(0)))
{
System.out.println("\n**ERROR06** - Quantity on hand must be between 0 and 500");
error=false;
...
Also, a couple of other things:
while (error == true) can be shortened to while(error).
Also, Integer.parseInt will throw a NumberFormatException if the input is not an integer - you need to catch and handle this.
Also, why do you need the second loop at all? It seems like it is only supposed to validate the input - if so, you can move this logic into the first loop and eliminate the second one. Only use loops for things that should happen repeatedly (like the user entering input data). There is no need to check the same input repeatedly.
Hello I am a high school student making a wordle program for my assignment, I've used an infinite loop for the method of my game but I'm having issues while using if statements in this loop. I've used "continue;" everywhere I think I can but it still prevents my code from repeating. I'm sorry if my code looks messy, things worked even less when I had methods because you can use "continue;" in a method that goes into a loop. The loop just refuses to continue even with "continue;" in my if statements me, my teacher and my classmates cannot think of a solution.
import java.util.; import java.io.; public class MyProgram{ //create default text colour public static final String ANSI_RESET = "\u001B[0m"; //create green text public static final String ANSI_GREEN = "\033[0;32m"; //create yellow tenxt public static final String ANSI_YELLOW = "\033[0;33m"; //create black backgound public static final String BLACK_BACKGROUND = "\033[40m"; //create yellow background public static final String YELLOW_BACKGROUND = "\033[43m"; //create scanner class object Scanner s = new Scanner(System.in); public static void main(String[] args){ //create array of 5 letter words String[] wordBank = {"storm","green","glass","mould","sweet", "stamp"}; //invoke user prompt userPromt(); //will store a random number from rng method int rng = rng(); //will store index of the word bannk with the same value of the RNG number String wordle = wordBank[rng]; //invoke game method game(wordle); } //will prompt user and tell them the rules static void userPromt(){ System.out.println("Welcome to Wordle! The goal of the game is"); System.out.println("to guess a randomly chosen 5 by guessing with "); System.out.println("5 letter words. For your guesses you"); System.out.println("recieve hints on your letters. Yellow means that the letter is"); System.out.println("in the word but not in the right place, green"); System.out.println("means that the letter you guessed is in the"); System.out.println("right place! Just keep trying your guesses."); System.out.println("Good luck and have fun!!," + YELLOW_BACKGROUND + ":)" + ANSI_RESET); } //wll generate a random number static int rng(){ //max for rng int max = 5; //minimum for rng int min = 0; //will generate the random number int randomNumber = (int)(Math.random() * (max - min + 1) + min); //will return the random number return randomNumber; } //will have game static void game(String wordle){ //create scanner class object Scanner s = new Scanner(System.in); //while tru will run methods for the game //counter int i = 0; System.out.println("Enter a word: "); //never use an infinite loop again... while(true){ //scan for user input String guessRaw = s.nextLine(); //convert to lowercase String guess = guessRaw.toLowerCase(); //counter increments after guess i++;
//if guess is less than 5 letters or more than 5 letter print invalid guess message
if (guess.length() < 5 || guess.length() > 5){
//error message for user
errorMessage();
i--;
//tell loop to continue
continue;
}//This is about where my code gets loopy with all the continue statements and stuff, //will print hints //create for loop which will loop the if statments and their checks for (int o = 0; o < 5; o++){ //create variables to make if staments look neater and easier to read char guessChar = guess.charAt(o); char wordleChar = wordle.charAt(o); //will print g letters if character from i index on guess and wordle are the same if (guessChar == wordleChar){ System.out.print(ANSI_GREEN + guessChar + ANSI_RESET); //tell loop to continue continue; } //Will check for yellow letters if above condition is not true else if (guessChar != wordleChar){ //create for loop which will loop for staments and their checks for (int n = 1; n < 5; n++){ //create vaiable to make if statment look better char wordleCheck = wordle.charAt(n); //this loop will print one yellow character regardless of the number of matches found while(true){ //if guess character is found with a match it will print a yellow character if (guessChar == wordleCheck){ System.out.print(ANSI_YELLOW + guessChar + ANSI_RESET); break; } else{ continue; } } } continue; }
//Issue ends here
//will print black letters if all other conditions false
else {
System.out.print(guessChar);
continue;
}
}
//will print win message if conditions prove true
//loop will check for letters guessed correctly add and to counter n
for (int l = 0; l < 5; l++){
int n = 0;
char guessChar = guess.charAt(l);
char wordleChar = wordle.charAt(l);
if (guessChar == wordleChar){
n++;
//just for good measure
continue;
}
//if the value of counter n reaches 5 the user wins the game.
if(n == 5){
System.out.println("You win! " + YELLOW_BACKGROUND + ":)" + ANSI_RESET);
break;
}
}
//will lose the gamne if user does not win after 6 guesses
//THIS ACTIVATES IF YOU WIN FOR SOME REASON?!?!?!?!
if (i >= 6){
lose(wordle);
break;
}
}
}
//error message for if guess word has wrong lenght
static void errorMessage(){
System.out.println("Word length invalid.");
}
//method
static void printHints(String guessString, String wordleString){
//create for loop which will loop the if statments and their checks
for (int i = 0; i < 5; i++){
//create variables to make if staments look neater and easier to read
char guess = guessString.charAt(i);
char wordle = wordleString.charAt(i);
//will print g letters if character from i index on guess and wordle are the same
if (guess == wordle){
System.out.print(ANSI_GREEN + guess + ANSI_RESET);
}
//Will check for yellow letters if above condition is not true
else if (guess != wordle){
//create for loop which will loop for staments and their checks
for (int n = 1; n < 5; n++){
//create vaiable to make if statment look better
char wordleCheck = wordleString.charAt(n);
//this loop will print one yellow character regardless of the number of matches found
while(true){
//if guess character is found with a match it will print a yellow character
if (guess == wordleCheck){
System.out.print(ANSI_YELLOW + guess + ANSI_RESET);
break;
}
}
}
}
//will print a black letter if all other conditions are false
else {
System.out.print(guess);
}
}
//will move cursor to the next line to make things look more organized
System.out.println("");
}
//Will print losing message
static void lose(String wordle){
System.out.println("You lose, the wordle was " + wordle);
}
//Will check for win conditions then print out win message
static void win(String guessString, String wordleString){
//loop will check for letters guessed correctly add and to counter n
for (int l = 0; l < 5; l++){
int n = 0;
char guess = guessString.charAt(l);
char wordle = wordleString.charAt(l);
if (guess == wordle){
n++;
}
//if the value of counter n reaches 5 the user wins the game.
if(n == 5){
System.out.println("You win! " + YELLOW_BACKGROUND + ":)" + ANSI_RESET);
}
}
}
static void infiniteLoopie(char guessChar, char wordleChar, char wordleCheck){
//this loop will print one yellow character regardless of the number of matches found
while(true){
//if guess character is found with a match it will print a yellow character
if (guessChar == wordleCheck){
System.out.print(ANSI_YELLOW + guessChar + ANSI_RESET);
break;
}
else{
continue;
}
}
}}
Here is a Pastebin with my code: https://pastebin.com/SPmTJJyj
Honestly I cannot think of a solution other than use a for loop instead but I would rather like to keep as infinite it and I just came here to see if there was something I was doing wrong or could do to fix it.
I'm making this thread on my phone so I'm sorry if things get formatted weirdly because of it, if it gets removed I will go onto my PC and try to make it proper
I'm solving this LeetCode exercise but I'm caught with a issue.
I came across the test case for input "dvdf" where my output was incorrect. I realized that my code behaved this way incrementally:
'd': Not in set, so add to set. Increment i
'v': Not in set, so add to set. Increment i
'd': Already in set, so clear set. (Do NOT increment i)
'd': Not in set, so add to set. Increment i
'f': Not in set, so add to set. Increment i
The correct longest substring without duplicates for "dvdf" is "vdf" but my resulting set was {d, f}. I realized that I had skipped reevaluating 'v', so I added i-- to my else-statement.
However, after adding this I got a timeout for an earlier test case "abcabcbb" where the set gets loops between {} and {b}.
I could totally just look at a solution, but I first want to know what I'm doing wrong so I can learn from it. Any help would be great. Thank you!
class Solution {
public int lengthOfLongestSubstring(String s) {
HashSet<Character> set = new HashSet<>();
int max_size = 0;
int i = 0;
while(i < s.length()){
if(!set.contains(s.charAt(i))){
set.add(s.charAt(i));
i++;
} else {
set.clear();
i--;
}
if(set.size() > max_size){
max_size = set.size();
}
}
return max_size;
}
}