While else statement equivalent for Java? - java

What is the Java equivalent of the while/else in Python? Because it doesn't work in Java. The first chunk was my python code and the second portion is my attempt to translate it into Java. Edit: tring to replicate while-else
while temp.frontIsClear():
if temp.nextToABeeper():
temp.pickBeeper()
count += 1
temp.move()
else:
if temp.nextToABeeper():
temp.pickBeeper()
count += 1
print "The count is ", count
Java Attempt
Robot temp = new Robot();
int count = 0;
while (temp.frontIsClear())
{
if (temp.nextToABeeper())
{
temp.pickBeeper();
count += 1;
}
temp.move();
}
else
{
if (temp.nextToABeeper())
{
temp.pickBeeper();
count += 1;
}
}
print ("The count is ", count);

The closest Java equivalent is to explicitly keep track of whether you exited the loop with a break... but you don't actually have a break in your code, so using a while-else was pointless in the first place.
For Java folks (and Python folks) who don't know what Python's while-else does, an else clause on a while loop executes if the loop ends without a break. Another way to think about it is that it executes if the while condition is false, just like with an if statement.
A while-else that actually had a break:
while whatever():
if whatever_else():
break
do_stuff()
else:
finish_up()
could be translated to
boolean noBreak = true;
while (whatever()) {
if (whateverElse()) {
noBreak = false;
break;
}
doStuff();
}
if (noBreak) {
finishUp();
}

Just use one more if statement:
if (temp.nextToABeeper())
// pick beer
} else {
while (temp.frontIsClear()) { /* your code */ }
}
Or:
if (temp.frontIsClear())
while (temp.frontIsClear()) { /* your code */ }
} else if (temp.nextToABeeper()) {
// pick beer
}

If you look at the Java Backus–Naur form Grammar (Syntax Specification), else never follows a while.
Your solution needs to be modified accordingly. You can put the while in an else, that way you handle the if statement.
if temp.nextToBeeper() {
//handle
} else {
while(temp.frontIsClear()) {
//handle
}
}

Try this:
Robot temp = new Robot();
int count = 0;
if (temp.frontIsClear())
{
while (temp.frontIsClear())
{
if (temp.nextToABeeper())
{
temp.pickBeeper();
count += 1;
}
temp.move();
}
}
else if (temp.nextToABeeper())
{
temp.pickBeeper();
count += 1;
}
print ("The count is ", count);

In Java
if is a conditional statement .
But
while is loop that is iterate again an again and stop itself when falsecondition occurred .

Related

How can I correct this int to boolean error?

Sorry I am having a mental block, can anyone see why I get the 'cannot convert from int to boolean' error message. Much appreciated
public static void main (String[]args) {
int max=10;
int sum=0;
int count=0;
for(int counter=0;counter=max-4;counter++) {
sum=max-4;
count=max-3;
for(sum=3;sum<5;sum++) {
if(count==0 && max>0){
System.out.println("Hello");
} else if (count<4) {
System.out.println("Go for it");
} else {
System.out.println("OK");
}
}
}
sum=sum+count;
System.out.println("Total = "+sum);
System.out.println("Max = "+count);
}
I feel like I have checked using the '==' for the if condition.
= is assignment, you need a comparison in the second term of your loop.
for(int counter=0;counter=max-4;counter++) {
should be
for (int counter = 0; counter < max - 4; counter++) {
(white space added, but note < is a comparison... perhaps you wanted <=).
In case of Java, the syntax of for loop is
for(initialization; Boolean_expression; update) {
// Statements
}
1) The initialization part executes only once when the flow enters the for loop for the first time
2) Next, the boolean expression is resolved according to the condition
3) Then next the update statement is resolved and after execution of the body of the for loop again the flow goes to the boolean expression and then update statement and the flow goes on.
So, In your program instead of a boolean expression, you have used an assignment operator which turns out to be 6 which is not 0 or 1. Boolean expression are true = 1 and false = 0. Hence the integer 6 cannot be converted to boolean. So, you can go with counter < max-4

Calling method within itself

I wanted to make an input which accepts numbers from 1 - 10 and prints the range.
I need to check if the input is an integer (check), check if the range is 0-10 (check), and if it's not any of those things, to ask the user again. So, a recursive method?
Currently I have this:
import java.util.Scanner;
import java.util.InputMismatchException;
public class FinalTest {
public static void main (String [] args) {
Scanner in = new Scanner(System.in);
int k = 0;
System.out.print("int - ");
try {
k = in.nextInt();
} catch (InputMismatchException e) {
System.out.println("ERR: Input");
System.exit(1);
}
if(k <= 10 && k > 0) {
for(int j=1; j <= k; j++) {
System.out.println(j);
}
} else {
System.out.println("ERR: Oob");
System.exit(1);
}
}
}
I would like to replace the "System.exit()" so that it re attempts to ask the user for input again.
calling main(); produces an error.
How do I correctly call the main method in this case?
Two choices here:
actually create a method and call that
simply use a loop
Loop could go like:
boolean askForInput = true;
while ( askForInput ) {
try {
k = in.nextInt();
askForInput = false;
} catch ...
print "not a number try again"
}
But beyond that: you still want to put this code into its own method. Not because that code should call itself, but for clarity reasons. Like:
public static int askForNumber(Scanner in) {
... code from above
return k;
}
And to answer your question: you do not want to use recursion here. You want to loop; and yes, recursion is one way to implement looping, but that is simply overkill given the requirement you want to implement here.
And for the record: when creating that helper method, you can actually simplify it to:
public static int askForNumber() {
while ( askForInput ) {
try ...
return in.nextInt();
} catch ...
print "not a number try again"
}
}
Beyond that: you typically use recursion for computational tasks, such as computing a factorial, or fibonacci number, ... see here for example.
for the part of the recursive method printing a range:
public void printAscending(int n) {
if (n > 0) {
printAscending(n - 1);
System.out.println(n);
}
}
I think using recursion is just too much for something that simple and would probably be more expensive. You can add a while loop around your scanning bit until the entered value is valid. I would also put the printing loop out of the while to not have to test a condition before printing since if you get out of the while loop, it means number if valid. You could test just the -1 value to exit process.
public class FinalTest
{
public static void main (String [] args)
{
Scanner in = new Scanner(System.in);
int k = 0;
do
{
System.out.print("int - ");
try
{
k = in.nextInt();
}
catch (InputMismatchException e)
{
System.out.println("ERR: Input");
System.exit(1);
}
}
while(!(k>0 && k<=10) && k!=-1);
if(k!=-1)
{
for(int j=1; j<=k; j++)
{
System.out.println(j);
}
}
else
{
System.out.println("Bye Bye.");
}
}
}
Okay, so what I personally do when I need to use recursion is I create a separate function/method for it. And when I need to restart the method, I just call it within itself. So it would be something like this:
private void recursiveMethod() {
// do stuff . . .
if (yourCondition) {
//continue to next piece of code
} else {
recursiveMethod();
}
}
But in big projects, try to stay away from recursion because if you mess up, it can

Is performance gained when using continue in a for-loop with many if-statements?

I have a for loop in a java program which iterates through a set of maps.
Inside the loop I have around 10 different if-statements which checks the name of each key inside the each map.
Example:
for (<String, Object> map : object.entrySet()) {
if (map.getKey().equals.("something") {
do_something;
continue;
}
if (map.getKey().equals.("something_else") {
do_something_else;
continue;
}
if ...
}
Do I gain any performance when adding continue-statements like this?
When I step through my code in my IDE and NOT have these continue statements, each if-statement will be tested even if the first one matches.
If I have them like this and the first if matches, the for loop will skip the next 9 if-statements and continue with the next object.
Maybe the compiled code will treat it differently and the added continue-statements actually makes the loop slower?
Instead of using continue all the time, do the getKey() just once and use else if:
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
if (key.equals("something")) {
// ...
} else if (key.equals("something else")) {
// ...
}
}
Or use a switch statement:
for (Map.Entry<String, Object> entry : map.entrySet()) {
switch (entry.getKey()) {
case "something":
// ...
break;
case "something else":
// ...
break;
}
If you want the current iteration to end after the first condition evaluates to true, you should use if-else-if-...-else. In my opinion, that's more clear than using continue, since that's what this syntax exists for.
for (<String, Object> map : object.entrySet()) {
if (map.getKey().equals.("something") {
do_something;
}
else if (map.getKey().equals.("something_else") {
do_something_else;
}
else if (...) {
...
}
... else {
...
}
}
With your current implementation, yes you are gaining a performance boost by skipping the remaining if statements using the continue keyword, although with only a constant of ten "if" statements, it's not that bad (10n = O(n) time). Having said that, the more practical way to approach this, as Eran stated, is to make use of else if statements, which will achieve the same result that you are currently using.
Because you have just a few values, IMO, you'll have a real performance improvement here if you map your strings to ints, since the int comparison is far faster than a String comparison.
Check this out
public class Lab1 {
public static void main(String[] args) {
usingStrings();
usingInts();
}
private static void usingInts() {
int[] samples = new int[100000000];
int[] values = {1,2,3,4};
for(int i=0;i<samples.length-1;i++) {
samples[i] = values[(int)(Math.random()*values.length)];
}
int total = 0;
long ini = System.currentTimeMillis();
for(int i=0;i<samples.length-1;i++) {
if (1 == (samples[i])) {
total+=doSomeJob();
}else if (2 == (samples[i])) {
total+=doSomeJob();
}else if (3 == (samples[i])) {
total+=doSomeJob();
}else {
total+=doSomeJob();
}
}
long end = System.currentTimeMillis();
System.out.println("Ints="+(end-ini));
}
private static void usingStrings() {
String[] samples = new String[100000000];
String[] values = {"one mule","two mules","three mules","four mules"};
for(int i=0;i<samples.length-1;i++) {
samples[i] = values[(int)(Math.random()*values.length)];
}
int total = 0;
long ini = System.currentTimeMillis();
for(int i=0;i<samples.length-1;i++) {
if ("one mule".equals(samples[i])) {
total+=doSomeJob();
}else if ("two mules".equals(samples[i])) {
total+=doSomeJob();
}else if ("three mules".equals(samples[i])) {
total+=doSomeJob();
}else {
total+=doSomeJob();
}
}
long end = System.currentTimeMillis();
System.out.println("Strings="+(end-ini));
}
/**
*
*/
private static int doSomeJob() {
int c = 0;
for(int i=0;i<1000;i++) {
c++;
}
return c;
}
}
output
Strings=962
Ints=6
which is actually how DBMS indexes work behind the scenes

Break statement inside two while loops

Let's say I have this:
while (a) {
while (b) {
if (b == 10) {
break;
}
}
}
Question: Will the break statement take me out of both loops or only from the inner one? Thank you.
In your example break statement will take you out of while(b) loop
while(a) {
while(b) {
if(b == 10) {
break;
}
}
// break will take you here.
}
It will break only the most immediate while loop. Using a label you can break out of both loops: take a look at this example taken from here
public class Test {
public static void main(String[] args) {
outerloop:
for (int i=0; i < 5; i++) {
for (int j=0; j < 5; j++) {
if (i * j > 6) {
System.out.println("Breaking");
break outerloop;
}
System.out.println(i + " " + j);
}
}
System.out.println("Done");
}
}
Only from the inner one. Use labeled break if you wish to break to specific loop
label1:
for(){
label2:
for(){
if(condition1)
break label1;//break outerloop
if(condition2)
break label2;//break innerloop
}
}
Also See
labeled break
#Abhishekkumar
Break keyword has it's derived root from C and Assembly, and Break it's sole purpose to passes control out of the compound statement i.e. Loop, Condition, Method or Procedures.
Please refer these...
http://tigcc.ticalc.org/doc/keywords.html#break
http://www.functionx.com/cpp/keywords/break.htm
http://en.wikipedia.org/wiki/Break_statement#Early_exit_from_loops
So, if you want to get out of Two loops at same time then you've to use two Breaks, i.e. one in inner loop and one in outer loop.
But you want to stop both loop at same time then you must have to use exit or return.
while (a) {
while (b) {
if (b == 10) {
break;
}
}
}
In the above code you will break the inner most loop where (ie. immediate loop) where break is used.
You can break both the loops at once using the break with label
label1:
while (a) {
while (b) {
if (b == 10) {
break label1;
}
}
}
It will break out of the loop that immediately encloses it.
You can however, break to a label:
myLabel:
while(a) {
while(b) {
if(b == 10)
break myLabel;
}
}
I don't generally like to use this pattern because it easily leads to spaghetti code. Use an unlabeled break or a flag to terminate your loop.
As a curious note, in PHP the break statement accept a numeric parameter which tells how many outer loops you want to break, like this:
$i = 0;
while (++$i) {
switch ($i) {
case 5:
echo "At 5<br />\n";
break 1; /* Exit only the switch. */
case 10:
echo "At 10; quitting<br />\n";
break 2; /* Exit the switch and the while. */
default:
break;
}
}
You can raise a flag to pass the information to the outer while loop. In this case the information can be stored in a variable breakOuterLoopFlag and the outer while loop acts according to this information.
See pseudo code below:
int breakOuterLoopFlag = 0;
while(a){
while(b){
if(b == 10) {
breakOuterLoopFlag = 1;
break;
}
}
if(breakOuterLoopFlag == 1) {
break;
}
}
A break statement will take you out of the innermost loop enclosing that break statement.
In the example the inner while loop.
The java break statement won't take you out of multiple nested loops.
Only the inner loop of course.

Java - add a return statement

I am learning java so bear with me on this if it seems basic. I have a method which I am trying to edit to return a value which is 'read in' - I am trying to return 'move'. However, due to the setup of the code the return falls outside the code block and forces me to return a null. Can someone edit the code so that it returns the 'move' value? I have been working on this for 2 days and I can't work it out - the try and catch seem to be causing the problem
public Move listenToEngineMove()
{
synchronized(engineReadBuffer)
{
int numRows=engineReadBuffer.size();
if(numRows==0);
for(int kk=0; kk<numRows; kk++)
{
String row=engineReadBuffer.get(kk);
row=row.toLowerCase();
if((row.contains("move "))||(row.contains(" ... ")))
if((!row.contains("illegal"))&&(!row.contains("error")))
try {
String[] tokens=row.replaceAll("\\<.*\\>"," ").split("\\s+");
Move move = new Move(tokens[tokens.length-1]);
jcb.makeAIsMove(move);
System.out.println("thread.... " + row);
}
catch (Exception x) {
System.out.println("Exception! : "+x.getMessage());
}
}
engineReadBuffer.clear();
}
return null;
}
Try this:
public Move listenToEngineMove() {
Move move = null;
synchronized (engineReadBuffer) {
int numRows = engineReadBuffer.size();
if (numRows == 0) ; // what on earth is this?
for (int kk = 0; kk < numRows; kk++) {
String row = engineReadBuffer.get(kk);
row = row.toLowerCase();
if ((row.contains("move ")) || (row.contains(" ... ")))
if ((!row.contains("illegal")) && (!row.contains("error")))
try {
String[] tokens = row.replaceAll("\\<.*\\>", " ").split("\\s+");
move = new Move(tokens[tokens.length - 1]);
jcb.makeAIsMove(move);
System.out.println("thread.... " + row);
} catch (Exception x) {
System.out.println("Exception! : " + x.getMessage());
}
}
engineReadBuffer.clear();
}
return move;
}
I'd recommend that you replace this:
catch(Exception x){System.out.println("Exception! : "+x.getMessage());}
with this:
catch(Exception e){
e.printStackTrace(); // Or, better yet, logging with Log4J
}
The complete stack trace gives more info than the message.
This line looks like a mistake to me. The semi-colon at the end looks out of place.
if (numRows == 0) ; // what on earth is this?
Your code looks awful. I find it hard to read, because you aren't consistent with your indentation and general code style. Style matters; it makes your code easier to read and understand. Adopt a better style and stick with it.
You will need to move 'Move' just inside synchronized block, It is important to keep it inside synchronized block to stay thread safe.
public Move listenToEngineMove()
{
synchronized(engineReadBuffer)
{
Move move =null;
int numRows=engineReadBuffer.size();
if(numRows==0);
for(int kk=0; kk<numRows; kk++)
{
String row=engineReadBuffer.get(kk);
row=row.toLowerCase();
if((row.contains("move "))||(row.contains(" ... ")))
if((!row.contains("illegal"))&&(!row.contains("error")))
try {
String[] tokens=row.replaceAll("\\<.*\\>"," ").split("\\s+");
move = new Move(tokens[tokens.length-1]);
System.out.println("thread.... " + row);
}
catch(Exception x){System.out.println("Exception! : "+x.getMessage());}
}
engineReadBuffer.clear();
return move;//this is inside synchronized block
}
}

Categories

Resources