I have this code which generates random number from an array, at a particular condition (when x and y both are equal to zero). I want the control to jump to the label. But the control never jumps to the label in any condition. I wanted to know that whether I am doing it right or not?
int[] arr = {0, 1, 2};
Random rn = new Random();
label: {
//some code
if (x != 0 && y !=0) {
//some code
} else {
break label;
}
}
Without examining whether you should, yes, you can use labeled statements with if in Java. According to the 1.7 specification
The Identifier is declared to be the label of the immediately contained Statement. [...] identifier statement labels are used with break (§14.15) or continue (§14.16) statements appearing anywhere within the labeled statement.
It goes on (emphasis added)
If the statement is labeled by an Identifier and the contained Statement completes abruptly because of a break with the same Identifier, then the labeled statement completes normally. In all other cases of abrupt completion of the Statement, the labeled statement completes abruptly for the same reason.
So if you break an if block (remember a block is a statement), you can exit the if body. Let's test it:
public static void main(String[] args) {
if (true) label: {
if (args != null)
break label;
System.out.println("doesn't get here");
}
System.out.println("Outside of labeled block");
}
Output:
Outside of labeled block
The break statement breaks loops and does not transfer control to the label.
Using a label with break is for when you have inner and outer loops. An unlabeled break breaks the inner most loop (the one you are in) whereas a labeled break allows you to specify an outer loop.
See: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html
Specifically the BreakWithLabelDemo
Try to Avoid using labels. What you could do there, is:
while(true) {
if(x == 0 && y == 0) {
break;
}
// some stuff with x and y
}
I suggest that you use a recursive function.
public void work(){
// some code
if (x != 0 && y != 0) {
//some code
} else {
work();
}
}
You cannot use break without loops
As far as I know, labels cannot be used arbitrarily around {}, you need to do them to mark a for, while or do-while loop
Related
I don't know interpret this code:
t:
while (true) {
break t;
}
Can you help me?
This construct called a "labeled break" and can be used to simultaneously break out of multiple nested loops.
To quote an example from an Oracle tutorial:
search:
for (i = 0; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length;
j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search;
}
}
}
Here, an unlabeled break (i.e. simply break) would only terminate the inner loop, whereas break search terminates both loops at once.
See Is using a labeled break a good practice in Java? for a relevant debate.
It's just a label that you place anywhere and then you can "break" or "continue" depending on your conditions.It can be used in nested if-else with for loopings in order to break several loops.
Here break t; simply means break out from the while loop that is labelled as t.
It's useful for breaking out of nested loops
This is called a 'level', the alternative to 'goto' in other languages. Although 'goto' is a reserved word in Java, it is not used in the language; Java has no goto. However, it does have something that looks a bit like a jump tied in with the break and continue keywords: a level.
A label is an identifier followed by a colon, like this: label1:
The only place a label is used in Java is right before an iteration statement. The reason to put a label before an iteration is if you’re going to nest another iteration or a switch inside it. That’s because the break and continue keywords will normally interrupt only the current loop, but when used with a label, they’ll interrupt the loops up to where the label exists:
label1:
outer-iteration {
inner-iteration {
//...
break; // (1)
//...
continue; // (2)
//...
continue label1; // (3)
//...
break label1; // (4)
}
}
In (1), the break breaks out of the inner iteration and you end up in the outer iteration. In (2), the continue moves back to the beginning of the inner iteration. But in (3), the continue label1 breaks out of the inner iteration and the outer iteration, all the way back to label1. Then it does in fact continue the iteration, but starting at the outer iteration. In (4), the break label1 also breaks all the way out to label1, but it does not re-enter the iteration. It actually does break out of both iterations.
Hope this help!!!
In the following code:
for (Iterator<MyClass> iterOuter = mList1.iterator(); iterOuter.hasNext();) {
mClass1 = iterOuter.next();
for (Iterator<MyClass> iterInner = mList2.iterator(); iterInner.hasNext();) {
mClass2 = iterInner.next();
if (...) {
continue;
}
else if (...) {
//code 1
}
else if (...) {
continue;
}
else if (...) {
//code 2
}
}
}
EDIT: code 1 & 2 are math calculation, in any moment ain't add or remove to the iterators.
When I inspect it with debugger I notice then after the last inner iteration, when I expect the debugger jump to the inner for line check the condition and then realize it's end of loop and jump back to outer for loop.
Instead after the inner for check (when the condition is not met and need to jump back to outer) the debugger jumps to the line with //code 2 , NOT executing the code there and then jumps back to outer for.
What's happening here? Is this some issue with the debugger or it's something with java, the if else if structure with the continue etc?
I'm going through my code to make sure it conforms to CheckStyle standards.
I personally feel that the rule "No Inner Assignments" makes the code more complicated to understand (you have to look in 3 places instead of 1).
Is there some way that I could preserve my single area by creating a {} block within the while loop to perform my assignments and return a boolean?!
What are your opinions?
File file = new File("C:\\test.txt");
FileInputStream fileInputStream = new FileInputStream(new FileInputStream(file));
// Inner Assignment
while ((int i = fileInputStream.readLine()) != -1)
{
//
}
// No Inner Assignment
int i = fileInputStream.readLine();
while(i!= -1)
{
//
i = in.readLine();
}
I encounter similar issues when I require a while loop which assigns a combination of some variable using, for example the ++ operator.
Would this for loop be considered a better alternative (it does comply with checkstyle)
for (int i = fileInputStream.readLine(); i != -1; i = fileInputStream.readLine())
{
//
}
You can rewrite your loop as an infinite loop with a break in the middle, like this:
while(true) {
int i = fileInputStream.readLine();
if (i == -1) break;
}
Note that i can be moved inside the loop: the only value that it can have upon exiting the loop is -1, so there is no reason to keep the variable visible outside the loop.
i saw how to break the loop (using label and break the label) .. but i want to break the first for loop depends on the second for loop :
for example :
public class HelloWorld {
static private int i;
public static void main(String[] args) {
int y = 20;
for (; y <= 30; y += 2)
{
System.out.printf("value of increamented y Value is %d\n", y);
increamentiValue();
}
}
private static void increamentiValue()
{
i = 0;
for (; i <= 5; i += 2) {
System.out.printf("value of i is %d\n", i);
}
}
}
for instance here i want to break the "y" loop depends on the number of iteration in "i" loop ..
for ex:
i want to break "y" for loop if the number iteriation in "i" loop is equal to 0 .. because in my program "i" checks the error ... in my ysytem error may occur any "i" .. if two times i dosnt have error (i==0) i want to break the "y" loop.
EX :
if
At y= 22 , i ==0; (no error occurs)
at y= 23 , i ==0; (no error occurs)
i dont want to proceed till 30. i want to break y loop .
Have increamenti_Value return a value that main uses to terminate the loop.
Separately, though, using an instance variable (i) in the for loop in increamenti_Value is a very suspect thing to do. It's also quite odd to use a for loop, leave out the initializer clause, and yet set the initial condition on the line above.
Have the incrementi_Value return the value of i and check that value in your y loop.
incrementi_Value == 0 ? break : continue;
Change private static void incrementi_Value -> private static int incrementi_Value
then place a return i; when you want to return the current value of i.
Instead of increamenti_Value() being void, make it return boolean - true if the caller should break, false otherwise:
private static boolean increamenti_Value() {
// return true if you want the caller to break
}
And instead of calling it like you are, call it like this:
if (increamenti_Value())
break;
Note that a called method having knowledge of when the caller should do something doesn't seem like a good design. You may want to reconsider your logic.
let say my code look like below
for(..)
for(..)
for(..){
break; //this will break out from the most inner loop OR all 3 iterated loops?
}
Your example will break out of the innermost loop only. However, using a labeled break statement, you can do this:
outer:
for(..)
for(..)
for(..){
break outer; //this will break out from all three loops
}
This will only break out from the inner loop. You can also define a scope to break out from. More from the language specs:
A break statement with no label
attempts to transfer control to the
innermost enclosing switch, while, do,
or for statement of the immediately
enclosing method or initializer block;
this statement, which is called the
break target, then immediately
completes normally.
Yes, without labels it will break only the most inner loop.
Instead of using labels you can put your loops in a seperated function and return from the function.
class Loop {
public void loopForXx() {
untilXx();
}
private void untilXx() {
for()
for()
for()
if(xx)
return;
}
}
From the most inner loop :)
int i,j,k;
for(i = 0; i < 2; i++)
for(j = 0; j < 2; j++)
for(k = 0; k < 2; k++)
{
printf("%d %d %d\n", i, j, k);
break;
}
Will produce :
0 0 0
0 1 0
1 0 0
1 1 0
You should take a look here: http://java.sun.com/docs/books/tutorial/java/nutsandbolts/branch.html
as often mentioned i don't like to break with a label eather. so while in a for loop most of the time i'm adding a boolean varible to simple exit the loop.. (only if i want to break it of cause;))
boolean exit = false;
for (int i = 0; i < 10 && !exit; i++) {
for (int j = 0; j < 10 && !exit; j++) {
exit = true;
}
}
this is in my opinion more elegant than a break..
Many people here don't like labels and breaking. This technique can be compared to using a 'goto' statement, a flow control statement which allows jumping out of a block of code in a non-standard way, obliviating use of pre- and post conditions. Edsger Dijkstra published a famous article in Communications of the ACM, march 1968, 'Goto statement considered harmful' (it's a short read).
Using the same reasoning presented in the article, returning from inside an iteration as suggested by TimW is also bad practice. If one is strict, to create readable code, with predictable entry- and exit points, one should initialize the variable which will hold the return value (if any) at the beginning of the method and return only at the end of a mehod.
This poses a challenge when using an iteration to perform a lookup. To avoid using break or return one inevitably ends up with a while-loop with a regular stop condition and some boolean variable to indicate that the lookup has succeeded:
boolean targetFound = false;
int i = 0;
while (i < values.size() && ! targetFound ) {
if (values.get(i).equals(targetValue)) {
targetFound = true;
}
}
if (!targetFound) {
// handle lookup failure
}
Ok, this works, but it seems a bit clunky to me. First of all I have to introduce a boolean to detect lookup success. Secondly I have to explicitly check targetFound after the loop to handle lookup failure.
I sometimes use this solution, which I think is more concise and readable:
lookup: {
for(Value value : values) {
if (value.equals(targetValue)) {
break lookup;
}
}
// handle lookup failure here
}
I think breaking (no pun intended) the rule here results in better code.
it will breake from most inner loop,
if you want to break from all, you can hold a variable and change its value when you want to break, then control it at the beginning of each for loop