not executing second condition in for loop - java

I am strange with something in for loop. If i call setCurrentId(1) then generateid will return 0(return statement execute inside for loop ). Again if i call with setCurrentId(2) it returns 0(return statement execute outside for loop ) which is not supposed to.
I have a profile ArrayList which has been created before with id 1,2,3,4. So i am now checking a random id with these id.But in the for loop it only execute 1st time.
public void setCurrentId(int id) {
Log.d("status scd :", "scI a " + id);
this.current_id = GenerateId(id);
Log.d("status scd :", "scI b " + this.current_id);
}
public int GenerateId(int profile_id) {
if (AppController.getInstance().getProfile() != null) {
Log.d("status scd :", "GI ");
for (int i = 0; i < AppController.getInstance().getProfile().size() && AppController.getInstance().getProfile().get(i).getId() == profile_id; i++) {
return i;
}
}
return 0;
}
Log result is :
status scd :: scI a 1
status scd :: GI
status scd :: scI b 0
status scd :: scI a 2
status scd :: GI
status scd :: scI b 0
so,i debug and found that 2nd condition is not executing after 1st call of setCurrentId().
When i place the 2nd condition inside if then it works fine. But don't know why this is happening.So, i am curious to figure it out.
here is corrected code :
public void setCurrentId(int id) {
Log.d("status scd :", "scI a " + id);
this.current_id = GenerateId(id);
Log.d("status scd :", "scI b " + this.current_id);
}
public int GenerateId(int profile_id) {
if (AppController.getInstance().getProfile() != null) {
Log.d("status scd :", "GI ");
for (int i = 0; i < AppController.getInstance().getProfile().size(); i++) {
if (AppController.getInstance().getProfile().get(i).getId() == profile_id) {
return i;
}
}
}
return 0;
}
And the log result :
status scd :: scI a 1
status scd :: GI
status scd :: scI b 0
status scd :: scI a 2
status scd :: GI
status scd :: scI b 1

Your condition in the For loop says AND (&&). The first loop looks for the condition to be true to iterate and since that being false it omits the loop.
Iteration is possible only with True functionality for any multiple conditions in for loop. In your second code snippet loop condition is true until i< the size of Profile List and hence loop being triggered.
#skyman statement Condition in for loop means 'do when true' so loop body is skipped. this is correct.
It is good practice to see the second code snippet in real time. Reason being is exception handling. Also, i see in your code snippet conventions are not being used just for your reference.Java Conventions

AppController.getInstance().getProfile().get(i).getId() == profile_id is probably false for first profile item so you do not step into loop and 0 is returned.
Condition in for loop means 'do when true' so loop body is skipped.

Related

Why does my method return the wrong value?

Even though my method operationsNeeded prints the correct value for my return-int "count1", the very next line it returns something else to my main method. I did not include the rest of my code, if needed I'd gladly provide it.
For example if operationsNeeded is executed 4 times, count1 is on 4 which is printed out as well. But for reasons unknown to me the System.out.println("check: " +count1); Statement is executed 4 times like this:
check: 4
check: 4
check: 3
check: 2
I would expect my program to execute this only once and then continue to the return statement.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int testcases = sc.nextInt();
int count =0;
while (count<testcases){
int numberOfColleagues = sc.nextInt();
sc.nextLine();
String startPieces = sc.nextLine();
int[] listOfcolleagues = listOfColleagues(numberOfColleagues, startPieces);
int count2 = operationsNeeded(listOfcolleagues, 1);
count++;
System.out.println(count2);
}
}
public static int operationsNeeded (int[] listOfColleagues, int count1){
//remove duplicates first
ArrayList<Integer> relevantList=removeDuplicatesAndSort(listOfColleagues);
System.out.println("relevantlist" + relevantList);
//check for smallestdelta & index
int [] deltaAndIndex = smallestDeltaHigherIndex(relevantList);
int delta = deltaAndIndex[0];
int index = deltaAndIndex[1];
if (delta==1){
for (int i=0;i<relevantList.size();i++){
if (i!=index){
relevantList.set(i,relevantList.get(i)+1);
}
}
}
if (delta>1 && delta<5){
for (int i=0;i<relevantList.size();i++){
if (i!=index){
relevantList.set(i,relevantList.get(i)+2);
}
}
}
if (delta>4){
for (int i=0;i<relevantList.size();i++){
if (i!=index){
relevantList.set(i,relevantList.get(i)+5);
}
}
}
System.out.println(count1);
int[] updatedList = new int[relevantList.size()];
for (int i=0; i<relevantList.size();i++){
updatedList[i]=relevantList.get(i);
}
if (!isAllTheSame(relevantList)) {
count1 +=1;
operationsNeeded(updatedList,count1);
}
System.out.println("check: " + count1);
return count1;
}
Your method is recursive. The "check: " line is printed on each level of that recursion, with the value that it currently has on that level. It first prints the "inner-most" value (4), than that of the level above (also 4), and finally hte value in the top-level, which is 2 after being incremented in the if above. And the value it returns is always the value from to top-level.
If you want to print it only once, you could print it on the inner-most level only, using else. However, that will still return the value from the top-level iteration; instead, keep track of the value returned from the recirsive call and update count1 accordingly.
if (! isAllTheSame(relevantList)) {
// we have to go deeper!
count1 = operationsNeeded(updatedList, count1 + 1);
} else {
// phew, finally done
System.out.println("check: " + count1);
}

2 Statements with OR in a do while loop

I want to end this Do While loop if the the pulls are 0 or the time is on 60 sek.
But if the pulls are at 0 the loop doesn't stop.
do{
try
{
Thread.sleep(1000);
sek++;
System.out.println(sek);
}
catch(Exception e)
{
System.out.println(e);
}
db = new BdsPostgres( );
db.select(Result.SET_1, "SELECT * FROM connection_overview WHERE leitung="+leitung+" AND status='pull' ");
db.naechsterDatensatz(Result.SET_1);
anzahlPulls = db.leseZeilen(Result.SET_1);
db.schliessen();
} while (anzahlPulls != 0 || sek != 60);
You want to use and instead of or , please note in while loop if the condition evaluates to true, it continues the loop, does not end it.
So actually your condition reads as - while either (anzahlPulls is not zero) or (sek is not 60) continue the loop. (that is when one of the condition is true continue the loop)
You actually want to use and - while both (anzajlPulls is not zero) and (sek is not 60) continue the loop. (that is break the loop when one of the conditions becomes false)
Example code -
do{
try
{
Thread.sleep(1000);
sek++;
System.out.println(sek);
}
catch(Exception e)
{
System.out.println(e);
}
db = new BdsPostgres( );
db.select(Result.SET_1, "SELECT * FROM connection_overview WHERE leitung="+leitung+" AND status='pull' ");
db.naechsterDatensatz(Result.SET_1);
anzahlPulls = db.leseZeilen(Result.SET_1);
db.schliessen();
}while (anzahlPulls != 0 && sek != 60);
You have got your logic wrong:
NOT ( A OR B ) = (NOT A) AND (NOT B)

While loop not checking all conditions

I have a loop that should stop executing only once both jobStatus(0) and jobStatus(1) returns 2
while(c.getStatus(0) != 2 && c.getStatus(1) != 2){
c.update();
}
System.out.println("Person id0: " + c.getStatus(0));
System.out.println("Person id1: " + c.getStatus(1));
Here is the update() method.
public void update() {
for(Map.Entry<Integer, Person> person : allPeople.entrySet()){ //check all jobs
Person person = person.getValue();
if(person.getStatus() != person.WORKING){
continue;
}
Date currentTime = new Date();
long startTime = person.getStartTime().getTime();
long requiredTime = person.getRequiredTime();
long finishTime = startTime + requiredTime;
if(finishTime <= currentTime.time()){
person.finished();
getMachineById(getAllocatedMachineId()).changeMachineStatus();
}
}
}
Output after loop ended:
Person id0: 2
Person id1: 1
Not sure why it's behaving the way it is, the long variables are correct (printing the variable reveals the current time increments correctly until it overtakes finish time - but then it exits the loop and doesn't continue for getStatus(1).
You got the condition wrong. It stops when one of c.getJobStatus(0) and c.getJobStatus(1) is two.
It should be:
while(c.getJobStatus(0) != 2 || c.getJobStatus(1) != 2){
c.updateJobs();
}
As long as one of them is not two, the loop should continue.
The loop entry condition is wrong.
You could have avoided the bug by translating what you want to do in code leading to a more natural:
while(!(c.getJobStatus(0) == 2 && c.getJobStatus(1) == 2)){ //while both are not 2
c.updateJobs();
}

How can I check an else statement correctly using &&?

Just a quick question, can i use this to include "left" "right"
back" and "forward" all together or do i have to do them separately?
An error came up, so if anyone knows how to include them all together then please help. Thanks
Scanner console = new Scanner(System.in);
for (int i = 0; i < 100; i++) {
System.out.println("Please type in either the word \"left\" or \"right\" or \"back\" or \"foward\": ");
String s = console.next();
if (s.equalsIgnoreCase("left")) {
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(0,100,S);
} if (s.equalsIgnoreCase("right")) {
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(100,0,S);
} if (s.equalsIgnoreCase("back")) {
myFinch.setWheelVelocities(-100,-100,S);
} if (s.equalsIgnoreCase("foward")) {
myFinch.setWheelVelocities(130,130,S);
} else if (s.equalsIgnoreCase != ("left" && "right" && "back" && "foward")) {
myFinch.quit();
}
I would go with a switch statement :
switch (s.toLowerCase()) {
case "left":
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(0,100,S);
break;
case "right":
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(100,0,S);
break;
}
First off to answer your question, in Java you should use String.equals to compare strings, or String.equalsIgnoreCase. This is because this example will fail:
String a = "a";
if (a == "a") {
// Will not be true because you are comparing the reference to the string "a"
} else if (a.equals("a")) {
// Will work because you are comparing on the value of the two strings
}
ref: == vs .equals
I noticed you did this in the first few statements, but on the last statement, the one in question, you did not.
While the statement you were trying to form was not necessary I find it would be useful to share the correct way to do it:
// OMITTED CODE
} else if (s.equalsIgnoreCase("left") && s.equalsIgnoreCase("right") && s.equalsIgnoreCase("back") && s.equalsIgnoreCase("foward") ) {
myFinch.quit();
}
You must make each boolean statement complete, in the sense that it must evaulate to a boolean.
s.equalsIgnoreCase != x// this is simply method so it could not be compared to anything using the != operator
("left" && "right" /* etc */ ) // "left", "right" are not booleans but simply strings.
Java is a very explicit language so shortcuts as the one you attempted are often far and few between.
Secondly you should use the format:
if (/* condition 1*/) {
// code if condition 1 is true
} else if (/* condtion 2 */) {
// code if condition 2 is true but condition 1 is false
} else {
// code if condition 1 and condition 2 are false
}
The else if statement is used to simplify code that would take the following format:
if (/* condition */) {
// code will run if condtion is true
} else {
if (/* sub-condition */) {
// code will run if sub-condition is true, but condition is false
} else {
if (/* sub-sub-condition */) {
// code will run if sub-sub-condition is true, but sub-condition and condition are false
} else {
// code will run if condition, sub-sub-condition, and sub-condition is false
}
}
}
To avoid long chains of such code:
if (/* condition */) {
// code will run if condtion is true
} else { if (/* sub-condition */) {
// code will run if sub-condition is true, but condition is false
} else { if (/* sub-sub-condition */) {
// code will run if sub-sub-condition is true, but sub-condition and condition are false
} else {
// code will run if condition, sub-sub-condition, and sub-condition is false
}}}
The formatting can be seen clearly from here to the current setup:
if (/* condition */) {
// code will run if condtion is true
} else if (/* sub-condition */) {
// code will run if sub-condition is true, but condition is false
} else if (/* sub-sub-condition */) {
// code will run if sub-sub-condition is true, but sub-condition and condition are false
} else {
// code will run if condition, sub-sub-condition, and sub-condition is false
}
These statements were created to read in a logical way:
If the first condtion is met follow the first set of instructions,
else if the first condition wasnt met then try the second condition and instructions,
else if the first two conditions failed try the third set!,
else Damn! Just resort to these instructions
Imagine a scenario where you are taking care of your friend's cat. You are unable to talk about how to care for the cat before your friend leaves but they left you a set of instructions:
Dear friend,
Thank you for looking after muffins. She is a very high maintenance cat.
She has four kinds of food and depending on her mood you should feed her one of
these four: "Purina Super Awesome Cat Time", "Cat Feast 2000", "Cat Chow", and
"Canned".
If you come over and she is waiting at the door give her the "Cat Fest 2000",
If she is not waiting at the door, but instead attacks your leg as you enter the
house you should give her the "Cat Chow",
If she is not at the door, and didn't attack you but is instead wearing a small hat
you should give her the "Purina Super Awesome Cat Time" and play a game of Bridge with
her.
If none of those things happened then give her the "Canned".
Thanks! See you Caturday!
Instead of sending yourself on this monstrous task, with clearly outlined danger, perhaps we want to write a very intelligent robot to go in and take care of the cat each day.
// Upon arrival
if ( Cat.isWaitingAtTheDoor() ) {
Cat.feed("Cat Fest 2000");
} else if ( Cat.didAttackWhenYouWalkedIn() ) {
Cat.feed("Cat Chow");
} else if ( Cat.isWearingSmallHat() ) {
Cat.feed("Purina Super Awesome Cat Time");
Cat.playBridgeWith(self);
} else {
Cat.feed("Canned");
}
So reformat your code to match that structure and you will find you don't need that last condition:
Scanner console = new Scanner(System.in);
for (int i = 0; i < 100; i++) {
System.out.println("Please type in either the word \"left\" or \"right\" or \"back\" or \"foward\": ");
String s = console.next();
if (s.equalsIgnoreCase("left")) {
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(0,100,S);
} else if (s.equalsIgnoreCase("right")) {
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(100,0,S);
} else if (s.equalsIgnoreCase("back")) {
myFinch.setWheelVelocities(-100,-100,S);
} else if (s.equalsIgnoreCase("foward")) {
myFinch.setWheelVelocities(130,130,S);
} else {
myFinch.quit();
}
}
The way you had it set up initially you essentially are not creating a branch structure.
consider this:
int i = 0;
if (i == 0) {
System.out.println("i = 0");
i = 1;
} if (i == 1) {
System.out.println("i = 1");
} else {
System.out.println("i is neither 1 or 0");
}
This will out put:
i = 0
i = 1
Not what we intended!
This is because the above code is equivalent to:
int i = 0;
if (i == 0) {
System.out.println("i = 0");
i = 1;
}
// Two separate statements altogether
if (i == 1) {
System.out.println("i = 1");
} else {
System.out.println("i is neither 1 or 0");
}
Whereas:
int i = 0;
if (i == 0) {
System.out.println("i = 0");
i = 1;
} else if (i == 1) {
System.out.println("i = 1");
} else {
System.out.println("i is neither 1 or 0");
}
Will give:
i = 0
What we wanted, now it is a branched statement, it checks the first if statement then all else if statements following and lastly if none were true resorts the else statement. This seems to be your intention since there is no space for variab;e reassignment between these if statements.
Since JDK 7 you can use strings in switches.
Means:
switch(s.toLowerCase()) {
case "left":
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(0,100,S);
break;
case "right":
myFinch.setWheelVelocities(90,90,S);
myFinch.setWheelVelocities(100,0,S);
break;
case 'back':
myFinch.setWheelVelocities(-100,-100,S);
break;
case "foward"
myFinch.setWheelVelocities(130,130,S);
break;
/** .. and other cases **/
default:
myFinch.quit();
}

Java: why isn't the updated value being returned?

public static int getElementIdx (DOMElement elt) {
int count = 1;
for (DOMElement sib = (DOMElement) elt.getPreviousSibling();
sib != null;
sib = (DOMElement) sib.getPreviousSibling())
{
System.out.println("sib "
+ sib.getTagName () + " elt " + elt.getTagName ());
if (sib.ELEMENT_NODE == sib.getNodeType () &&
sib.getTagName () == elt.getTagName ()) {
System.out.println (count);
count++;
}
}
return count;
}
count always returns 1. However, inside the for loop, it returns the incremented count value. This is really strange, I thought declaring a local variable count outside of the for loop should work....
The count usage is fine--the inner if statement is likely never true.
The culprit is likely to be
sib.getTagName() == elt.getTagName()
You need to check String equality using equals():
sib.getTagName().equals(elt.getTagName())

Categories