Reputation: 135
So I debugged and went to the base of the problem. Basically, I am running a few testcases and
int no_of_test = Integer.parseInt(in.readLine());
for(int t = 0;t<no_of_test;t++){//do something}`
Works fine. However,
for(int t=0;t<Integer.parseInt(in.readLine());t++){//do something}
Here, it keeps waiting for input after each iteration.
In python I could do for t in range(int(input())
and it wouldn't block for input after every iteration, why is that not the case in JAVA? What am I missing?
Upvotes: 0
Views: 93
Reputation: 47971
According to the Java Language Specification:
BasicForStatement: for ( ForInitopt ; Expressionopt ; ForUpdateopt ) Statement ForStatementNoShortIf: for ( ForInitopt ; Expressionopt ; ForUpdateopt ) StatementNoShortIf ForInit: StatementExpressionList LocalVariableDeclaration ForUpdate: StatementExpressionList StatementExpressionList: StatementExpression StatementExpressionList , StatementExpression
14.14.1.2. Iteration of for Statement
Next, a for iteration step is performed, as follows:
If the Expression is present, it is evaluated. If the result is of type Boolean, it is subject to unboxing conversion (§5.1.8).
In other words, t < Integer.parseInt(in.readLine())
is executed once per each iteration of the loop.
It is explained better in the Java Tutorial:
The for statement provides a compact way to iterate over a range of values. Programmers often refer to it as the "for loop" because of the way in which it repeatedly loops until a particular condition is satisfied. The general form of the for statement can be expressed as follows:
for (initialization; termination; increment) { statement(s) }
When using this version of the for statement, keep in mind that:
- The initialization expression initializes the loop; it's executed once, as the loop begins.
- When the termination expression evaluates to false, the loop terminates.
- The increment expression is invoked after each iteration through the loop; it is perfectly acceptable for this expression to increment or decrement a value.
If you want something similar to for t in range(int(input())
, you can use the Streams API:
import static java.lang.Integer.parseInt;
import static java.lang.System.console;
// option 1
try (final BufferedReader console = new
BufferedReader(new InputStreamReader(System.in))) {
IntStream.range(0, parseInt(console.readLine())).forEach(i -> {
System.out.println(i);
});
}
// option 2 (fails in some IDEs as console() will return null)
IntStream.range(0, parseInt(console().readLine())).forEach(i -> {
System.out.println(i);
});
Upvotes: 0
Reputation: 990
There are different code constructions.
In the Python sample range()
is function. It's called once and returns integer sequence as a result. So, loop iterates over the sequence of values.
In the Java sample t < Integer.parseInt(in.readLine())
is the loop condition and it must be checked for every iteration. Java analog to your python code can be:
IntStream.range(0, Integer.parseInt(in.readLine())).forEach((e) -> {
//...
});
Upvotes: 1
Reputation: 12937
It keeps waiting because second statement is a condition which is checked before each iteration.
for(int t=0; t<Integer.parseInt(in.readLine()); t++)
Statement 1: sets a variable before the loop starts (int t = 0).
Statement 2: defines the condition for the loop to run. If the condition is true, the loop will start over again, if it is false, the loop will end.
Statement 3: increases a value (t++) each time the code block in the loop has been executed.
The only case when a loop can end is when you don't give a input which will keep waiting for long till you enter one, so it's a never ending loop.
If you still want to end the loop, input something which is not a number.
Upvotes: 1
Reputation: 1902
With
for(int t=0;t<Integer.parseInt(in.readLine());t++){//do something}
The Integer.parseInt(in.readLine())
piece is re-evaluated every iteration.
Whereas with
int no_of_test = Integer.parseInt(in.readLine());
for(int t = 0;t<no_of_test;t++){//do something}
The Integer.parseInt(in.readLine())
is evaluated once only.
Upvotes: 1
Reputation: 32535
In first case you are doing in.read()
outside the loop
In second case, you got in.read()
inside loop execution.
Remember that loop condition is evaluated on every iteration, so you are doinb in.read
on every iteration.
Maybe you wanted to do this
for(int t=0,tests=<Integer.parseInt(in.readLine());t<tests;t++) {body}
?
Upvotes: 0