This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 6 years ago.
I use if() sentences to control some transition, but it does not work. How can I solve these problems? I use the EasyFSM library to implement the simulation based on Finite State Machine.
I attach my own code. This is only the part of my code that has the problem I want to solve.
I think that there is no syntax error, but when I run the program there is no transition (the f.ProcessFSM(~) does not work) and there are only IDLE states (it is the first state of the FSM.)
How can I solve this problem?
FSM f = new FSM("C://Users//losin//Desktop//file//PMC.xml", new FSMAction() {
#Override
public boolean action(String curState, String message, String nextState, Object args) {
return true;
}
});
for(int j=0; j <10 ; j++) {
list.add(f.getCurrentState().toString());
if(f.getCurrentState().toString()=="IDLE") {
double rnd1 = Math.random();
if(list.contains("PROCESS_COMPLIETED")==true) {
if(rnd1 < 0.05) {
f.ProcessFSM("FAIL");
} else if(rnd1 < 0.15) {
f.ProcessFSM("CLEAN");
} else {
f.ProcessFSM("LOAD");
}
} else {
if(rnd1 < 0.05) {
f.ProcessFSM("FAIL");
} else {
f.ProcessFSM("LOAD");
}
}
} else if(f.getCurrentState().toString()=="PREPARE") {
f.ProcessFSM("PROCESS_START");
} else if(f.getCurrentState().toString()=="PROCESS") {
double rnd2 = Math.random();
if(rnd2 < 0.05) {
f.ProcessFSM("FAIL");
} else {
f.ProcessFSM("COMPLETE");
}
} else if(f.getCurrentState().toString()=="PROCESS_COMPLETED") {
f.ProcessFSM("UNLOAD");
} else if(f.getCurrentState().toString()=="FAILURE") {
f.ProcessFSM("FIX");
} else {
f.ProcessFSM("CLEAN_END");
}
}
CSVUtils.writeLine(writer, list);
writer.flush();
writer.close();
if(f.getCurrentState().toString()=="IDLE") //is wrong use
if(f.getCurrentState().toString().equals("IDLE"))
This condition is never correct
if(f.getCurrentState().toString()=="IDLE") {
you are comparing references and not the content of the object
String objects must be compared using the equals method
if("IDLE".equals(f.getCurrentState().toString()))
Related
This question already has answers here:
"Missing return statement" within if / for / while
(7 answers)
Closed 1 year ago.
here is my code. I am simply wanting to return the int value if it matches if not I don't want to return anything but it keeps giving me errors saying that I need to add a return statement to my code. I'm new to Java so I don't quite understand why it's not working.
Any help you can provide would be greatly appreciated,
public int faceIndex(String currentWheelFace) {
for (int i = 0; i < wheelFaces.length; i++) {
if (wheelFaces[i] == currentWheelFace) {
return i;
}
}
}
Should be like this
You should have a return statement outside loops
public int faceIndex(String currentWheelFace) {
int number;
for (int i = 0; i < wheelFaces.length; i++) {
if (wheelFaces[i] == currentWheelFace) {
number = i;
break;
}
}
return number;
}
In your code, the return breaks out of the method as soon as the condition is satisfied.
But if it falls through by exhausting the for loop, then there is no return value provided. That will generate a compile error, needing a return value.
So, provide a default return value and then the calling code can check for validity. You would have to document the range of values of valid returns, but it seems that returning -1 could indicate the value is not found.
The problem is that, if ur condition fails, the function will return nothing, then it will become a void function instead of int. Also your return statement is inside a loop, which means that ur function will return more than one value if WheelFaces[i] becomes equal to CurrentWheelFace more than once.... If u dont want ur function to do that then just add a break statement:
public int faceIndex(String currentWheelFace) {
int W;
for (int i = 0; i < wheelFaces.length; i++) {
if (wheelFaces[i] == currentWheelFace) {
W=i;
break;
}else{
W=//some other default int value;
break;
return W;
}
}
}
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 .
I'm currently trying to create a randomly generated string. Problem is, with the way I have it setup it continues to add on to itself.
My code ( I'm calling a lot of static variables from another class so don't worry about that portion)
class Generate1 extends Thread{
#Override
public void run() {
while(RUNNING == true){
generate();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void generate(){
for(int i=0;i<length;i++){
int decider = rando.nextInt(6)+1;
if(decider == 1){
sb1.append("A");
}
if(decider == 2){
sb1.append("B");
}
if(decider == 3){
sb1.append("C");
}
if(decider == 4){
sb1.append("D");
}
if(decider == 5){
sb1.append("E");
}
if(decider == 6){
sb1.append("F");
}
}
Log.d("PSS",sb1.toString()); // this here is the stringbuilder being outputted
}
}
if I set length to 2, in my log it would look something like:
DF
DFCA
DFCAEF
instead of my desired output:
DF
CA
EF
how do I fix this? ( I know this is probably a stupid question but it's late and pondering through code hurts my eyes and brain )
edit - shmosel brought light to what was wrong. It was a really simple fix to me overlooking something
You're using the same StringBuilder instance for each call to generate(). Use a fresh one instead:
private void generate(){
StringBuilder sb1 = new StringBuilder(length);
// ...
}
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
I'm using this check in android with new floating labels for edit text and method works like this. If string gets empty text or numbers, i'm setting an error message to edit text. It works if i only check if string is empty, but when i try to check if string is getting some numbers, it isn't working. Here is my code:
private boolean validateLastName() {
String checkLastName = inputLastName.getText().toString();
if (checkLastName.trim().isEmpty())
for (int i = 0; i < checkLastName.length(); i++) {
if (!Character.isLetter(checkLastName.charAt(i))) {
inputLayoutLastName.setError(getString(R.string.err_msg_last_name));
requestFocus(inputLastName);
return false;
} else {
inputLayoutLastName.setErrorEnabled(false);
}
}
return true;
}
and this is how i'm using it:
if (!validateLastName()) {
return;
}
Edit:
For Example this is working fine, but above code does nothing and below code is showing an error(I mean an error message for user):
private boolean validateName() {
if (inputName.getText().toString().trim().isEmpty()) {
inputLayoutName.setError(getString(R.string.err_msg_name));
requestFocus(inputName);
return false;
} else {
inputLayoutName.setErrorEnabled(false);
}
return true;
}
With minor changes in your solution I think it will work. I haven't tried it in android but I have tried something similar in java(no android) in order to validate the logic.
private boolean validateLastName() {
String checkLastName = inputLastName.getText().toString().trim();
if (checkLastName.isEmpty()) {
inputLayoutLastName.setError(getString(R.string.err_msg_last_name));
requestFocus(inputLastName);
return false;
} else {
for (int i = 0; i < checkLastName.length(); i++) {
if (!Character.isLetter(checkLastName.charAt(i))) {
inputLayoutLastName.setError(getString(R.string.err_msg_last_name));
requestFocus(inputLastName);
return false;
}
}
}
inputLayoutLastName.setErrorEnabled(false);
return true;
}
if (!validateLastName()) {
return;
}
Change this to
return !validateLastName();
EDIT:
You actually don't even check for numbers in your if tests, that's why it's not returning false if there are numbers.
private final CharSequence NUMBERS = "0123456789";
if (inputName.getText().toString().trim().isEmpty() &&
inputName.getText().toString.contains(NUMBERS)) { }