2 Statements with OR in a do while loop - java

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)

Related

for loop decrease variable in loop

I want to decrease the variable loop in for loop. What can I do?
When I do loop--.It will forever loop happened
for (int loop=0;loop<number.length-1;loop++)
{
if (number[loop] != number[loop+1])
{
if (loop > 0 && freq_array[loop-1]== 1 )
{
loop--; //this line
continue;
}
freq=1;
freq_array[loop]=freq;
}
else if (number[loop] == number[loop+1])
{
freq++;
freq_array[loop]=freq;
}
}
#cameron1024 advice me to use while loop but it has forever loop anyway?
while (loop<number.length-1)
{
if (number[loop] != number[loop+1])
{
if (loop > 0 && freq_array[loop-1]== 1 )
{
continue;
}
else
{
freq=1;
freq_array[loop]=freq;
loop++;
}
}
else
{
freq++;
freq_array[loop]=freq;
loop++;
}
}
Firstly, read https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html
Secondly, a for loop is just a while loop with decoration. For example:
for (<initializer>; <termination>; <increment>) {
<loop body>
}
is identical (with minor scope changes) to:
<initializer>;
while (<termination>) {
<loop body>
<termination>
}
The reason it is looping forever is that you have not changed your termination condition to match the fact that the variable is now decreasing. Your termination condition checks that loop does not go above a certain value. And since loop only ever decreases, that condition is always satisfied, and so the loop continues infinitely.
P.S. avoid naming variables like_this in java, they are typically done likeThis
i think you want this.
for (int loop = number.length - 1; loop > 0; loop--)
If you mean you want to count down:
Just do for(int i=10;i>=0;i--)
int i = 10 makes a new int initialised with 10
The next part is your loops exit condition.
as long a i>=10,the loop will run
And lastly i-- decrement the variable i
Your loop is infinite because the loop++ in the making of the loop and your loop-- are falling together creating a
int i = 1;
while(i < 10) {
i++;
i--;
}
while (loop<number.length-1)
{
if (number[loop] != number[loop+1])
{
freq=1;
freq_array[loop]=freq;
loop++;
}
else
{
freq++;
if (loop > 0 && freq_array[loop-1]== 1 )
{
freq_array[loop-1]=freq;
}
else
{
freq_array[loop]=freq;
}
loop++;
}
}
I'm done now thank you every one.

How the conditions ( sc == rs + 1 || sc == rs + MAX_RESIZERS) can be achieved in addCount function of ConcurrentHashMap( JDK1.8 or later)

I read the source code of addCount function in ConcurrentHashMap,
but I don't understand when the conditions ( sc == rs + 1 || sc == rs + MAX_RESIZERS) can be achieved.
why not use sc == ( rs<<<RESIZE_STAMP_SHIFT ) +1 || sc == ( rs<<<RESIZE_STAMP_SHIFT ) + MAX_RESIZERS
In the addCount(long x, int check) function of ConcurrentHashMap(JDK1.8 or later), there are some code as the following
if(check >=0{
Node<K, V>[] tab, nt;
int n, sc;
while (s >= (long) (sc = sizeCtl) && (tab = table) != null &&
(n = tab.length) < MAXIMUM_CAPACITY) {
int rs = resizeStamp(n);
if (sc < 0) {
// the problem is here :
// the condition sc == rs + 1 || sc == rs + MAX_RESIZERS
// seems always to be false
if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||
transferIndex <= 0)
break;
if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))
transfer(tab, nt);
} else if (U.compareAndSwapInt(this, SIZECTL, sc,
(rs << RESIZE_STAMP_SHIFT) + 2))
transfer(tab, null);
s = sumCount();
}
}
I have done some reserch job to understand how resizeStamp(n) works and how varaible sizeCtl works.
So basically, when one thread first get the opportunity to resize the bucket array in ConcurrentHashMap, it will do operation
U.compareAndSwapInt(this, SIZECTL, sc,(rs << RESIZE_STAMP_SHIFT) + 2)
to make the sizeCtl become a negative value which can denote that there are some thread doing resizing on the bucket array.
when sizeCtl become negative, the lower 16 bit contains information about how many threads are doinig resizing concurrently.
Here are my thoughts :
since varible sc is a local int variable as the code shows int n, sc;
after s >= (long) (sc = sizeCtl) is executed ,
the value of sc will never be changed for a theard in one iteration.
I listed all the code snnippet that have chance to change sizeCtl in one round while loop
Two pieces in the addCount function :
else if (U.compareAndSwapInt(this, SIZECTL, sc, (rs << RESIZE_STAMP_SHIFT) + 2))
the purpose of it is trying to contend on the opportunity to be the first thread that do resizing
if ( U.compareAndSwapInt(this, SIZECTL, sc, sc + 1) )
the purpose of it is trying to contend on the opportunity to help resizing
Three pieces in transfer fucntion
sizeCtl = Integer.MAX_VALUE;
this is to cope with OOP error
sizeCtl = (n << 1) - (n >>> 1);
this will happen when all elements in old table have been transfered to new table , the last thread which has not returned from transfer will set sizeCtl to next threshhold, which is 0.75 * (2n), notice n is old capcity. 2n is new capacity
U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, sc - 1)
this is to do resizing thread number control, which can identify one Thread is going to return from transfer
According to the all above info, I found :
After enter the if branch if (sc < 0), which means the sizeCtl have been assigned by (rs << RESIZE_STAMP_SHIFT) + 2, sc shuold be a "large" negative number with higher 16 bits computed from resizeStamp(n). The conditions
sc == rs + 1
||sc == rs + MAX_RESIZERS
could never be achieved given the fact that
The MAX_RESIZERS equals 65535
The maximum value of rs is Integer.numberOfLeadingZeros(MAXIMUM_CAPACITY ) | (1 << (RESIZE_STAMP_BITS - 1)), which equals 32769
I think the following conditions make more sense
sc == ( rs<<<RESIZE_STAMP_SHIFT ) +1 to judge whether all threads finished resizing
sc == ( rs<<<RESIZE_STAMP_SHIFT ) + MAX_RESIZERS to judge whether resizing threads has already achieved maxiumum limit MAX_RESIZERS.
Can someone help me to explain if I am wrong, thanks a lot !
The follwing is a little experiment I did to verify my thought
Thanks for the suggestion from Carlos Heuberger
can you post a Minimal, Complete, and Verifiable example to demonstrate the problem?
First, copy the ConcurrentHashMap source code to your own package
Second, do some necessary modification to make it can be compiled (eg: change package declaration, make Unsafe instance works, copy ThreadLocalRandom to your package as well, since the ConcurrentHashMap used ThreadLocalRandom.probe() function, which is not public )
Third, reduce MAX_RESIZERS to 2, as the documentation shows, this should ensure there are at most 2 threads can do resizing concurrently
private static final int MAX_RESIZERS = 2;
Fourth, add the following code snippet into the customized ConcurrentHashMap class
public static void main(String[] args) {
ConcurrentHashMap hashMap = new ConcurrentHashMap(8);
for(int i = 0; i< 300; i++)
{
new Thread() {
#Override
public void run() {
hashMap.put(Thread.currentThread().getId(),"id: "+Thread.currentThread().getId());
}
}.start();
}
}
Fifth, add the following code snippet into the transfer function of ConcurrentHashMap . To suspend any thread that entered into transfer
if (nextTab == null) { // initiating
try {
#SuppressWarnings("unchecked")
Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1];
nextTab = nt;
} catch (Throwable ex) { // try to cope with OOME
sizeCtl = Integer.MAX_VALUE;
return;
}
nextTable = nextTab;
transferIndex = n;
}
// The following added code here is to suspend Threads !!!!
try {
String s = new String();
synchronized (s)
{
s.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
Six, add the Thread break point in the following code line in addCount function
( Tip: I used Idea Intellij , choose "Thread" option can suspend each thread in your application , otherwise it will only suspend only the first Thread which executed to the break point)
if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))
transfer(tab, nt);
Then run the main function, you will see more than 2 threads entered transfer function, which means MAX_RESIZERS does not take any effect.
I have submitted this question as a bug report to Oracle. It has passed the evaluation and become visible on jdk bug database with bug id : JDK-8214427
Here is the link for the bug report : BUG: JDK-8214427. Notice the fix method given in the bug report is wrong due to my mistake
Summary :
The conditions
( sc == rs + 1 || sc == rs + MAX_RESIZERS)
should be changed to
sc == ( rs<<<RESIZE_STAMP_SHIFT ) +1 || sc == ( rs<<<RESIZE_STAMP_SHIFT ) + MAX_RESIZERS
Fixed JDK-12 code is now available here
if (check >= 0) {
Node<K,V>[] tab, nt; int n, sc;
while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
(n = tab.length) < MAXIMUM_CAPACITY) {
int rs = resizeStamp(n) << RESIZE_STAMP_SHIFT;
if (sc < 0) {
if (sc == rs + MAX_RESIZERS || sc == rs + 1 ||
(nt = nextTable) == null || transferIndex <= 0)
break;
if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1))
transfer(tab, nt);
}
else if (U.compareAndSetInt(this, SIZECTL, sc, rs + 2))
transfer(tab, null);
s = sumCount();
}
}

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();
}

looping over a try/catch block?

I am trying to write a try catch block like the following, but put it inside a loop. My issue is that when i put it in a while loop, it runs x amount of times. i want it to stop when the first try is successful. but give the option to run up to 3 times.
try {
myDisplayFile();
} catch (FileNotFoundException e1) {
System.out.println("could not connect to that file..");
e1.printStackTrace();
}
public static void myDisplayFile() throws FileNotFoundException{
Scanner kin = new Scanner(System.in);
System.out.print("Enter a file name to read from:\t");
String aFile = kin.nextLine();
kin.close();
Scanner fileData = new Scanner(new File(aFile));
System.out.println("The file " + aFile + " contains the following lines:");
while (fileData.hasNext()){
String line = fileData.next();
System.out.println(line);
}//end while
fileData.close();
}
int max_number_runs = 3;
boolean success = false;
for( int num_try = 0 ; !success && num_try < max_number_runs ; num_try++ )
{
try
{
/* CODE HERE */
success = true;
}
catch( Exception e )
{
}
}
int someCounter = 0;
boolean finished = false;
while(someCounter < 3 && !finished) {
try {
//stuff that might throw exception
finished = true;
} catch (some exception) {
//some exception handling
someCounter++;
}
}
You can break; within a try catch block and it will exit the loop that it's in (not just the try catch block), but from a readability stand point, this posted code might be better.
finished = true should be the final line of the try block. It won't throw an exception. And it will only execute if every other line of the try block executed without an exception. So if you get to finished = true, you didn't throw and exception, so you can toggle your flag and exit the loop.
Otherwise, if an exception is thrown, the finished = true; line won't execute. You'll deal with the exception, then increment the someCounter++ variable.
This is ideal from a readability standpoint because all possible while loop exits are marked in the conditional part of the while loop. The loop will continue until either someCounter is too large, or finished returns true. So if I'm reading your code, all I have to do is look through your loop for the parts where these variables are modified, and I can quickly understand the loop logic, even if I don't yet understand everything the loop is doing. I don't have to hunt for break; statements.
I hope I understood your problem correctly. Here's a way.
int noOfTries = 0;
boolean doneWithMyStuff = false;
final int MAX_LOOP_VAL = 10;
int noOfLoops = 0;
while(noOfTries < 3 && noOfLoops < MAX_LOOP_VAL && !doneWithMyStuff) {
try {
// Do your stuff and check success
doneWithMyStuff = true;
}
catch (Exception e) {
noOfTries++;
e.printStackTrace();
}
finally {
// Close any open connections: file, etc.
}
noOfLoops++;
}

Categories