So Im creating a Helper method in Java to calculate postage based on size, but I can't seem to figure out the return part. Im still new to helper methods and accessors etc. Im using Eclipse and its telling me "Add return statement" but I did.. What am I doing wrong here?
Here is my code:
//Helper Method.
public int calculatePostageCost() {
double postCost;
if(satchelSize.equals("small"))
postCost = 10;
else if(satchelSize.equals("Medium") || satchelSize.equals("medium"))
postCost = 13;
else if(satchelSize.equalsIgnoreCase("Large") || satchelSize.equals("large"))
postCost = 17;
else {
return calculatePostageCost();
}
}
The problem is that you do not have a guaranteed return statement at the end of the function. What would happen if your function does not encounter a satchel size, which is either "small", "medium", etc, you will return the value of what your function calculatePostageCost returns (I will return to that later).
In every other case, however, you do not have a return in your function. When you encounter "small" as satchel size, you enter the first if block of code, where you will set postCost to 10, then you jump over the rest of the code (since it is all else if).
Most likely you are missing a statement like return postCode; below the else block. This would at least eliminate the error message from eclipse. I am not fully sure about your code, but you could have an endless recursion here. Your else block might be a problem:
else {
return calculatePostageCost();
}
You need to check if it is possible, that in the next call of this recursion, the else block will not be reached. When this is not the case, you will have an endless recursion everytime you enter this function while you are in a state where the satchel size is not "small", "medium", etc, because you won't have a chance to change the state and get out of these calls anymore.
Don't use strings to compare your size, create an enum to do that:
public enum Size {
SMALL, MEDIUM, LARGE
}
private Size satchelSize; ....
public int calculatePostageCost() {
switch(satchelSize) {
case SMALL:
return 10;
case MEDIUM:
return 13;
case LARGE:
return 17;
}
}
If you are very keen on keeping the strings you can switch on strings too:
private String stachelSize = ....;
public int calculatePostageCost() {
switch(satchelSize.toUpperCase()) {
case "SMALL":
return 10;
case "MEDIUM":
return 13;
case "LARGE":
return 17;
default:
throw new AssertionError("Don't know satchel size " + satchelSize);
}
}
Note that your original code had
else {
return calculatePostageCost();
}
Which would call the same function again, which would end up in the same else branch, calling the same function again, which would end up in the same else branch, which.... would eventually give a StackOverflowException.
(I understand that strictly it does not answer your question 'why doesn't this compile'.)
The problem is that your return statement is within the scope of the else statement ,it should be outside like this : `
public int calculatePostageCost() {
double postCost;
if(satchelSize.equals("small"))
postCost = 10;
else if (satchelSize.equals("Medium") || satchelSize.equals("medium")){
postCost = 13;
else if(satchelSize.equalsIgnoreCase("Large") || satchelSize.equals("large"))
postCost = 17;
return postCost;
}
If you return calculatePostageCost() you create a recursive loop which causes a stack overflow error.
Do like this,
//Helper Method.
public int calculatePostageCost() {
int postCost = 5; // i don't know about default conndition, i am taking 5
if(satchelSize.equals("small"))
postCost = 10;
else if(satchelSize.equals("Medium") || satchelSize.equals("medium"))
postCost = 13;
else if(satchelSize.equalsIgnoreCase("Large") || satchelSize.equals("large"))
postCost = 17;
}
return postCost ;
}
You have to return value on every possible scenario. Right now you are returning (infinite recursion thus stak overflow will happen) only single in case if package is not small not medium nor large. You have to return value for every of this variants, like that:
public int calculatePostageCost() {
int postCost=1234; // default cost for not small nor medium nor large package
if(satchelSize.equals("small"))
postCost = 10;
else if(satchelSize.equals("Medium") || satchelSize.equals("medium"))
postCost = 13;
else if(satchelSize.equalsIgnoreCase("Large") || satchelSize.equals("large"))
postCost = 17;
return postCode
}
Or even better
public int calculatePostageCost() {
if(satchelSize.equalsIgnoreCase("small"))
return 10;
else if(satchelSize.equalsIgnoreCase("Medium"))
return 13
else if(satchelSize.equalsIgnoreCase("Large"))
return 17;
return 12345; // cos of non small, medium nor large package
}
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;
}
}
}
i have a loop which iterates equal to the length of an array, inside this loop i have a method which do some processing and have if-else structure inside. i want that if certain condition is true, then re-iterate the whole loop else continue.
the Minimum working code is provided.
for(int xx=0;xx<temp.length;xx++)
{
rule=temp[xx][1];
cons=temp[xx][2];
fp.factprocess(fact, rule, vars, cons);
}
contents of fp.factprocess are like
if(condition==true)
make xx = 0 in the parent loop
else
continue
i dont know how do i do it, i used return statement but it has to be in the end and can not be in the if-block.
Return a boolean from the condition test. If boolean true, set xx to -1 (to be incremented to 0) in the loop.
for(int xx=0;xx<temp.length;xx++)
{
rule=temp[xx][1];
cons=temp[xx][2];
boolean setXXtoZero = fp.factprocess(fact, rule, vars, cons);
if(setXXtoZero) xx=-1;
}
fp.factprocess:
return condition;
Yes, there can be a return statement in the if block.
public int getValue(int val){
if ( value == 5 ){
return value;
}
else{
return 6;
}
}
for instance, is valid Java code.
public int getValue(int input){
if ( input == 5 ){
return input;
}
}
on the other hand, is not, since you don't return anything if input does not equal 5, yet the method has to either return an int, or throw an Exception.
That's probably what your problem is: you need to provide a return statement for all possible scenario's.
If you want to modify the xx variable of the loop, I suggest to return a boolean in your factprocess method.
for (int xx = 0; xx < temp.length; xx++) {
rule = temp[xx][1];
cons = temp[xx][2];
boolean shouldRestart = fp.factprocess(fact, rule, vars, cons);
if (shouldRestart) {
xx = 0;
}
}
Pass xx to factprocess() and assign the return to xx
for(int xx=0;xx<temp.length;xx++)
{
rule=temp[xx][1];
cons=temp[xx][2];
xx = fp.factprocess(fact, rule, vars, cons, xx);
}
Inside factprocces()
if (condition == true) {
return 0
} else {
return xx
}
import java.util.*;
class A{
static int count=0;
static String s;
public static void main(String z[]){
int n;
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
System.out.println(noOfBouncy(n));
}
public static int noOfBouncy(int k){
int limit=(int)Math.pow(10,k);
s=new String("1");
int num=Integer.parseInt(s);
while(num<limit){
if(isIncreasing(s) || isDecreasing(s) ){
}
else{
count++;
}
num++;
s=new String(Integer.toString(Integer.parseInt(s)+1));
}
count=limit-count;
return count;
}
}
public static boolean isIncreasing(String s){
int len=s.length();
for(int i=0;i<len-1;i++){
if(s.charAt(i)>s.charAt(i+1)){
return false;
}
}
return true;
}
public static boolean isDecreasing(String s){
int len=s.length();
for(int i=0;i<len-1;i++){
if(s.charAt(i)<s.charAt(i+1)){
return false;
}
}
return true;
}
I have given the definitions to the two functions used isIncreasing() & isDecresing()
The program runs well for the value of n<7 but does not respond for values above it, Why ?
I accept the programming style is very immature,please ignore.
I've tried to execute it with n=7 and it finishes in 810ms, returning 30817.
However, I recommend to you to optimize the performance of your program by saving unnecessary object instantiation: It will be better if you maintain the counter in num, and convert it to string just once, at the beginning of the loop:
int num=1;
while (num < limit)
{
s=Integer.toString(num);
if (isIncreasing(s) || isDecreasing(s))
{
}
else
{
count++;
}
num++;
}
Like this it takes just 450ms to finish.
The program was not actually stuck but it is taking way too much time to complete its execution when value of 'n' is larger.
So now the question is, I need to optimize the code to take minimum time #Little have an optimization bit that's not enough.
Any hint would be appreciable.
To increase the performance you should avoid the conversation to String and do the check with numbers.
As it doesn't matter for the result if you start the comparison from left to right or from right to left one computational solution could be.
as pseudo code
1) compare the value of the right most digit with the digit on it's left
2) is it lower --> we found a decreasing pair
3) else check if it is bigger --> we found an increasing pair
4) else --> not a bouncy pair
5) if we found already one decreasing and one increasing pair it's bouncy number
6) divide the number by ten if it's bigger then ten repeat with step 1)
The method to check if it's a bouncy number could look like this
static boolean isBouncyNumber(int number) {
boolean increasingNumber = false;
boolean decreasingNumber = false;
int previousUnitPosition = number % 10;
int remainder = number / 10;
while (remainder > 0) {
// step 1
int currentUnitPosition = remainder % 10;
if (currentUnitPosition > previousUnitPosition) {
// step 2
decreasingNumber = true;
} else if (currentUnitPosition < previousUnitPosition) {
// step 3
increasingNumber = true;
}
// step 5
if (decreasingNumber && increasingNumber) {
return true;
}
// step 6
previousUnitPosition = currentUnitPosition;
remainder = remainder / 10;
}
return decreasingNumber && increasingNumber;
}
I want to know the difference between these two codes even though they produce the same output:
CODE 1:
class ret {
public static int add(int x) {
if(x!=0)
return x+add(x-1);
return x;
}
public static void main(String args[]) {
System.out.println(add(5));
}
}
CODE 2:
class ret {
public static int add(int x) {
if(x!=0)
return x+add(x-1);
return 0;
}
public static void main(String args[]) {
System.out.println(add(5));
}
}
They both output 15 but how come the second code also output's 15 instead of zero?My understanding is that the last call would be add(0) for code 2 and it would return zero.I also want to know is it okay to use multiple return statements or use a single return statement and replace the rest with local variables.I remember reading that single entry single exit model is a good practice.
This is a recursive method, so when x != 0, you will return the result of "x added to calling the method again with (x-1)". The final call will always return x == 0 or constant = 0, so you will return 15 from both versions.
Single return vs. multiple return is a matter of debate. The former should be preferred as a rule. Generally it will be obvious where multiple return statements are acceptable as it will be simpler to understand the method with them than with the alternative code constructs required to engineer a single exit point. Also note you could rewrite add as:
public static int add(int x) {
return x == 0 ? 0 : (x + add(x-1));
}
Version 1:
add(5)
call add(4)
call add(3)
call add(2)
call add(1)
call add(0)
return (x = 0)
return (x = 1) + (add(x-1) = 0) = 1
return (x = 2) + (add(x-1) = 1) = 3
return (x = 3) + (add(x-1) = 3) = 6
return (x = 4) + (add(x-1) = 6) = 10
return (x = 5) + (add(x-1) = 10) = 15
Version 2:
add(5)
call add(4)
call add(3)
call add(2)
call add(1)
call add(0)
return (constant = 0) // the only difference
return (x = 1) + (add(x-1) = 0) = 1
return (x = 2) + (add(x-1) = 1) = 3
return (x = 3) + (add(x-1) = 3) = 6
return (x = 4) + (add(x-1) = 6) = 10
return (x = 5) + (add(x-1) = 10) = 15
The use of multiple return statement versus using a single exit point cannot be answered with an easy one-line answer. I guess the best answer you can get is "it depends on your company's standards".
Single exit point is a very good standard, even though I don't personally endorse it. You end up having methods that always have a single return statement at the end, so you never get in a position where you are looking for those many possible return statement while editing someone else's code. I believe that developers that used to code in C tend to follow this standard (see this question).
I, for one, perfer using multiple return statements when it can help simplify the code. One case where I like to use it is to prevent cascading braces in my code. For instance, in the following example:
private int doSomething (int param) {
int returnCode;
if (param >= 0) {
int someValue = param * CONSTANT_VALUE;
if (isWithinExpectedRange (someValue)) {
if (updateSomething (someValue)) {
returnCode = 0;
} else {
returnCode = -3;
}
} else {
returnCode = -2;
}
} else {
returnCode = -1;
}
return returnCode;
}
I find this type of coding to be very confusing when reading it. I tend to change this type of code to:
private int doSomething (int param) {
if (param < 0) {
return -1;
}
int someValue = param * CONSTANT_VALUE;
if (!isWithinExpectedRange (someValue)) {
return -2;
}
if (!updateSomething (someValue)) {
return -3;
}
return 0;
}
The second example looks cleaner, and clearer, to me. Even more when the actual code has some extra coding in the else blocks.
Again, this is personal tastes. Some company might enforce a single exit point, some might not, and some developers prefer single exit point. The bottom line is, if there's a guideline available for you to follow in your environment, then do so. If not, then you can chose your own preference base partly on these arguments.
I'm pretty new to java, but I'm trying to make a simulation of the finger game, 'Sticks', using my limited knowledge. This may not be the neatest, but if you're going to make a suggestion on me to do something, link a page explaining what that thing is, and I'll read it.
Ok, so the issue comes up basically when I call a method to decide who's turn it is and trying to return the value for the "count" up to 5, but it's not returning to main()
public static int TurnCalcBB(int PLH, int PRH, int BRH, int BLH, int Death)
{
//Attacking with bot Right hand
Random botAtk = new Random();
if(botAtk.nextInt(2) == 1 && PRH <= 5)
{
PRH = BRH + PRH;
JOptionPane.showMessageDialog(null,"Your right hand is now at " + PRH);
return PRH;
} else if(botAtk.nextInt(2) == 0 && PLH <= 5){
PLH = BRH + PLH;
JOptionPane.showMessageDialog(null, "Your left hand is now at " + PLH);
return PLH;
}
return Death;
}
Death is there because I was getting an error telling me that I always need to return SOMETHING so I'm returning a static value.
Basically, the problem is getting PLH (player left hand) or PRH (player right hand) to return to main. If I'm not wrong, they should return as their initial variable name (PL, and PR) with the returned value correct? If not, what can I do to fix this?
The code is a lot larger than this, and this issue is happening throughout the whole program, so I'm showing just 1 method and assuming they're all the same issue; the methods are almost all the same.
Also, while I'm typing a question already, is nextInt() the best way to do a random number generator? When I had it as nextInt(1) it was exclusively attacking the left hand, and when I switched it to nextInt(2) now it's attacking both, but occasionally the code... "crashes" (what I mean by crashes is that it generates a number outside of what the If statements are looking for). I obviously need to to generate either a 1 or a 2 (or 0 and 1 if 0 counts).
You can change your code to
public static Integer TurnCalcBB(int PLH, int PRH, int BRH, int BLH, int Death)
{
//Attacking with bot Right hand
Random botAtk = new Random();
if(botAtk.nextInt(2) == 1 && PRH <= 5)
{
PRH = BRH + PRH;
JOptionPane.showMessageDialog(null,"Your right hand is now at " + PRH);
return PRH;
} else if(botAtk.nextInt(2) == 0 && PLH <= 5){
PLH = BRH + PLH;
JOptionPane.showMessageDialog(null, "Your left hand is now at " + PLH);
return PLH;
}
return null;
}
NOTE: make sure you first check for null values where you call this function.
You are generating random number twice, this is why you can observe "strange" behvior.
Random botAtk = new Random();
if(botAtk.nextInt(2) == 1 && PRH <= 5) {
...
}
else if(botAtk.nextInt(2) == 0 && PLH <= 5) {
...
}
Try generating random only once:
Random botAtk = new Random();
boolean right = botAtk.nextInt(2) == 1; // flip coin only once
if(right && PRH <= 5) {
...
}
else if(!right && PLH <= 5) {
...
}
I know the answer will not get accepted, because there is an accepted one, but nevertheless:
I suspect that you have a wrong understanding of method parameter passing in Java.
What I read from your question and comments is that you expect this to work:
public static int psInt = 0;
static void main() {
int someNumber = 1;
int someOtherNumber = 5;
method1( someNumber, someOtherNumber );
// You expect "someNumber" to be 6 right now.
// But in fact, the value will be unchanged.
// What WILL work: psInt is 0 now
method3(); // this method will modify the static class var
// psInt is 5 now.
}
static void method1( int numParam, int someothervalue ){
numParam = numParam + someothervalue;
}
static void method2( int someNumber, int someothervalue ){
someNumber = someNumber + someothervalue; // <- same name won't work either!
}
public static void method3(){
psInt = 5;
}
But in Java method arguments are passed by value. That is: a copy!
So no matter how you name the variables and arguments, you will never have an "out" argument here.
What you can do:
In a static method, you can use and modify static class variables.
In a non-static method, you can use and modify non-static and static class variables.
You can pass a State-Object, of which you can modify field values.
You can return a value.
... there are more possibilites. These just to start with.
In your case, 4. does not make so much sense, because you wouldn't know if it is the new right or left hand value.