for (int i = lowerBound; i == upperBound; i++) {
//Code goes here
}
I want the last time the for loop is run to have i equaling upperBound. Is this the right syntax? If so why might one ever use <= or >=?
Thanks in advance. :)
A for loop can always be translated to a while loop as follows:
for(initialization; condition; step) {
block;
}
To
initialization;
while (condition) {
block;
step;
}
So if your condition is i == upperBound, the loop will never run, because the condition doesn't start out as true. <= will do what you want, though.
for (int i = lowerBound; i == upperBound; i++) {
//Code goes here
}
The part inside for loop executes when it checks the constraint/condition mentioned inside for loop statement.
Example
for( int i =0; i == 10 ; i++){
saySomething();
}
will run only when i == 10 ie i would have been i=10 , while if you had written i<10 or i<=10 it would have run each time that condition is true.
Here is a quick example : link for for loop.
To run all + equals to upperBound, you need to use <=
One may might use >= if you're counting backwards, <= and if you're counting forwards.
Use:
i <= upperBound
inside the loop.
The reason being that the loop is testing against all constraints in that loop and will only run when it ticks these off as being true. i is only equal to upperbound in one case and never while i it is also equal to lowerbound, so it won't run.
(Eek. First ever answer here! I hope this helps!)
Related
I need to modify the program so that for all values of k that are larger than or equal to 0, the program works as it did before, but for all values of k less than 0, the program displays, k, k-1, k-2, … 0. You can only use for loops.
So my code is this, using while loops,
while (i != k && k > 0) {
i = i + 1;
System.out.println(i);
}
while (k <= 0) {
System.out.println(k);
k = k + 1;
}
I successfully did it for the positive numbers, but I am having issues with negatives.
here is the for loop i wrote for the positives
for (int i = 0; i <= k; i = i + 1) {
System.out.println(i);
}
please help!!!!
The Oracle documentation for The for Statement says (in part)
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.
tl;dr you could do something like
for (; i != k && k > 0;) {
System.out.println(++i);
}
for (; k <= 0; k++) {
System.out.println(k);
}
I have 2 ArrayLists of varying sizes. Example -
Array1.size() = 10
Array2.size() = 5
I want at all times these arrays to have same size. Thus, I have another class to ensure this. But obviously, it isn't working for me. Please help!
Below is that Class code -
for (int i = Array2.size(); i == Array1.size(); i++) {
Array2.add(i, "Test");
}
The above loop for just doesn't add 'Test' to the Array2 so it matches the size of Array1. Any ideas guys? Please help!
Your loop uses the wrong condition.
for (int i = Array2.size(); i == Array1.size(); i++) {
Array2.add(i, "Test");
}
This would mean the loop runs while i == Array1.size(), which is of course nonsense.
try
for (int i = Array2.size(); i < Array1.size(); i++) {
Array2.add(i, "Test");
}
As per the doc for loop is:
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.
In your case the loop is:
for (int i = Array2.size(); i == Array1.size(); i++) {
Array2.add(i, "Test");
}
It starts from 5 (Arrays2.size()) and checks whether i==10 which is not true (read false) and so it terminates without doing anything. It does not get into the loop at all.
Since i is never equal to Array1.size(), this loop never adds anything
for (int i = Array2.size(); i == Array1.size(); i++) {
Array2.add(i, "Test");
}
I've got 2 for loops, one nested inside of another. They loop through a 2D array of buttons to get the source of each button thats been clicked using the action listener.
When the button is found I pass the position/array indexs of the button to an external method. However when the button is found from the array of buttons the first for loop evaluates its termination condition to FALSE but still increments the value of i. Leading to an off by one error. My code is in the standard action performed method, with "event" being the ActionEvent. buttons[][] is a JButton array defined as an instance variable. It is of size 10 x 10 and is already added to the panel.
int i = 0; //this will loop through the columns in the array
int j = 0; //loop through the rows
boolean locatedSource = false; //allows me to escape both loops
for(i = 0; !(locatedSource) && i < buttons.length; i++) //problem here, when i < buttons.length is FALSE i still gets incremented, leading to an off by one error
{
for(j = 0; !(locatedSource) && j < buttons.length; j++)
{
if(event.getSource() == buttons[i][j])
{
locatedSource = true;
break;
}
}
}
//do stuff with i and j in another method. Leads to array out of bounds error / off by one error
}
I should of mentioned, I'm not looking to solve this problem with the use of labels, they seem to be discouraged.
Explanation of the problem
The increment expression of a for loop is executed after each loop iteration not before. See the following quote from the Oracle 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.
For loop solution
You can re-write your loop so that the increment is the first statement inside the loop.
for (i = 0; !(locatedSource) && i < buttons.length;) {
i++;
for (j = 0; !(locatedSource) && j < buttons.length;) {
j++;
if (event.getSource() == buttons[i][j]) {
locatedSource = true;
}
}
}
While Loop Version
Given that the loop variables are both initialised outside of the loop and you don't want to use a for-loop increment expression it might be clearer to rewrite the code to use while-loops as follows:
while (!(locatedSource) && i < buttons.length) {
i++;
while (!(locatedSource) && j < buttons.length) {
j++;
if (event.getSource() == buttons[i][j]) {
locatedSource = true;
}
}
}
Three possible solutions:
Explicitely set a "found" index and do not reuse your for loop indices.
Factor the searching out in an own method and return directly from the loop.
Decrement i by 1 after finishing the loops.
Use some boolean flag set it in inner loop and check it in the beginning of outer loop.
Here is code:
boolean found = false;
for (i = 0; i < 10; i++) // problem here, when i < buttons.length is FALSE i still gets
// incremented, leading to an off by one error
{
if (found) {
i--;
break;
}
for (j = 0; j < 5; j++) {
if (i == 5 && j == 3) {
found = true;
break;
}
}
//if (found) {
// break;
//}
}
Your code contains a comment "problem here, when i < buttons.length is FALSE i still gets incremented, leading to an off by one error", which is wrong in the ordering of the events.
First the cycle update block gets executed (like i++) and after that the condition is checked (like `i < buttons.length').
Meaning, that i == buttons.length is the correct state after the cycle ends without triggering the locatedSource condition.
At the moment, I have this:
do{
if (i < y){ //y is a constant
ObsHandler.obsPartsHandler(); //increment i twice
ObsHandler.search();
}
else {
break;
}
} while (!endline.equals(null)); // endline is changed during each loop cycle
With this loop, and the inputs I have, endline can not be null; this renders the while loop breaking condition redundant. When I try and convert this loop to a for loop, I get a misplaced construct error from Eclipse.
i.e:
for (i < y) {
ObsHandler.obsPartsHandler(); //increment i twice
ObsHandler.search(); }
Whilst, the while loop I have works, it seems like bad practice to me.
Any suggestions? Thanks.
If you don't need to check endLine, you can still use a while loop:
while (i < y) {
ObsHandler.obsPartsHandler(); //increment i twice
ObsHandler.search();
}
If you also need to check endLine:
while (i < y && !endline.equals(null)) {
ObsHandler.obsPartsHandler(); //increment i twice
ObsHandler.search();
}
Note: the difference between do / while (your initial code) and while { } is that in the first case the loop is always run at least once. With a while { }, it is not run at all if the condition is not true at the beginning. That is the same behaviour as a for loop (won't run if the condition is false before the loop).
If you want to use a for loop, you need to have all three parts of a standard for. Since you have two conditions, they need to be both included in the condition part:
for ( ; i < y && !endline.equals(null); ) {
ObsHandler.obsPartsHandler();
ObsHandler.search();
}
You probably have some initialization code for i, like i=0, which could also go into the initialization section of the for loop. Otherwise, if all you have is a set of conditions to check without some array or list you are iterating, while or do is really the better fit.
A while loop seems like the natural choice for your code. I would just simplify it to:
do {
ObsHandler.obsPartsHandler(); //increment i twice
ObsHandler.search();
} while (i < y && !endline.equals(null)); // endline is changed during each loop cycle
or, if you need to check the conditions before:
while (i < y && !endline.equals(null)) {
ObsHandler.obsPartsHandler(); //increment i twice
ObsHandler.search();
}
for (boolean start=true;(start || endline != null) && i < y;){
start=false;
ObsHandler.obsPartsHandler(); //increment i twice
ObsHandler.search();
}
(startendline != null) is only tested the second time.
i < y is only tested the first time.
for example would this be constant or change with each pass?
for(int i = 0; i < InputStream.readInt(); i++)
for(int i = 0; // executed once
i < InputStream.readInt(); // executed before each loop iteration
i++ // executed after each loop iteration
) {
....
}
The first section is executed once before the looping starts. The second section is checked before every loop and if it is true, the loop gets executed, if false the loop breaks. The last part is executed after every iteration.
It executes every time. The for syntax is sugar for
int i = 0
while(true)
{
if(!(i < InputStream.readInt()))
{
break;
}
// for body
i++
}
For times when a control-flow diagram is actually the best graphical representation of a concept.
http://upload.wikimedia.org/wikipedia/commons/0/06/For-loop-diagram.png
I think the main issue is the question: does
i < InputStream.readInt();
get executed each loop iteration? Yes, it does.
In this case it's not changing any sensitive variable, the only variable actually changing in your code is i, but InputStream.readInt() will be run each iteration to make the comparison and will therefore run readInt() again on InputStream.
What about something like:
for (int i=0; i < xObj.addOne().parseInt(); i++)
(given the method addOne returns a string representation of an integer one greater)
Is my "check" incrementing the value that would be incremented if I called xObj.addOne() like normal? Yes. and does it stay incremented to the next loop iteration? Yes.
It's just like doing
int x = 0;
for (int i=0; i < ++x; i++);
This will never terminate, as ++x is always greater than x (which is also i)
What about a nontrivial example?
int x = 6;
for (int i=0; i < x--; i++) {
System.out.print(i+" ");
}
outputs
0 1 2