Missing return statment - java

I wrote this small program as practice in Java(it simulates the 7 electrical logic gates), as I am currently learning it. But when I try to compile it, it gives me several errors stating "MISSING RETURN STATEMENT", but only for the subroutines that have 2 if statements(AND, OR, NAND and NOR). I am wondering if there is something that I don't know about Java if statements. I am also wondering if there is a way in Java to do if(X && Y), like in C. Anyway, here is the code:
package logic;
public class logic {
boolean AND(boolean A, boolean B) {
if(A==true) {
if(B==true)
return true;
}
else
return false;
}
boolean OR(boolean A, boolean B) {
if(A==false) {
if(B==false)
return false;
}
else
return true;
}
boolean NOT(boolean A) {
if(A==true)
return false;
else
return true;
}
boolean NAND(boolean A, boolean B) {
if(A==true) {
if(B==true)
return false;
}
else
return true;
}
boolean NOR(boolean A, boolean B) {
if(A==false) {
if(B==false)
return true;
}
else
return false;
}
boolean XOR(boolean A, boolean B) {
if(A==B)
return false;
else
return true;
}
boolean XNOR(boolean A, boolean B) {
if(A==B)
return true;
else
return false;
}
}
and the error message:
logic/logic.java:10: error: missing return statement
}
^
logic/logic.java:18: error: missing return statement
}
^
logic/logic.java:32: error: missing return statement
}
^
logic/logic.java:40: error: missing return statement
}
^
4 errors
all help or suggestions is accepted.
For some reason when I tried to use if(A==true && B==true)before it didn't work, but now it is.

Java is not like Python where the compiler understand that code blocks are stated by simple indentation. I would recommend always using braces { } to open a close a new code block even if is one liner. Just to rewrite one of your gates:
boolean AND(boolean A, boolean B) {
if(A==true) {
if(B==true) {
return true;
}
//missing return here!
//fix it by adding a return
return false;
} else {
return false;
}
}

As others have pointed out, you really miss out some return statements. Here is the short version you are looking for:
public class Logic {
boolean AND(boolean A, boolean B) {
return A && B;
}
boolean OR(boolean A, boolean B) {
return A || B;
}
boolean NOT(boolean A) {
return !A;
}
boolean NAND(boolean A, boolean B) {
return !(A && B);
}
boolean NOR(boolean A, boolean B) {
return !(A || B);
}
boolean XOR(boolean A, boolean B) {
return A ^ B;
}
boolean XNOR(boolean A, boolean B) {
return !(A ^ B);
}
}
Note that class names in Java should start with a capital letter by convention.

You lack return statements for some code paths.
In OR, what happens if A is true and B is false?

Some of your methods have paths that result in no return value.
For example:
boolean NOR(boolean A, boolean B) {
if(A==false) {
if(B==false)
return true;
}
else
return false;
}
If A == false and B == true, there is no return statement to run. This is why you are getting that compiler error.
This is perhaps made more obvious by putting brackets around all of your if statements:
boolean NOR(boolean A, boolean B) {
if(A==false)
{
if(B==false)
{
return true;
}
//No return here
}
else
{
return false;
}
//No return here
}

Aside from the return statement errors, you are making your code way too complex. Java already has compound logical operators that can greatly simplify how you are reasoning about your program.
// no need for A == true, A is either already true or false
// just combine them using the && operator
boolean AND(boolean A, boolean B) {
return A && B;
}
Similarly for OR:
boolean OR(boolean A, boolean B) {
return A || B;
}
You can also build logic gates from other logic gates, EX NOT + OR == NOR
boolean NOT(boolean A) {
return !A;
}
boolean OR(boolean A, boolean B) {
return A || B;
}
Combine the two to create NOR:
boolean NOR(boolean A, boolean B) {
return NOT( OR(A, B) );
}
Using this, see if you can compose the rest yourself.

Missing return statement error means that The function declaration says it returns something, but there exists atleast one flow where it does not return anything. Eg. In the code for And - if A is true and B is false. Modified the code :
package logic;
public class Logic {
boolean AND(boolean A, boolean B) {
if (A == true && B == true) {
return true;
}
return false;
}
boolean OR(boolean A, boolean B) {
if (A == false && B == false) {
return false;
}
return true;
}
boolean NOT(boolean A) {
if (A == true) {
return false;
}
return true;
}
boolean NAND(boolean A, boolean B) {
if (A == true && B == true) {
return false;
}
return true;
}
boolean NOR(boolean A, boolean B) {
if (A == false && B == false) {
return true;
}
return false;
}
boolean XOR(boolean A, boolean B) {
if (A == B) {
return false;
}
return true;
}
boolean XNOR(boolean A, boolean B) {
if (A == B) {
return true;
}
return false;
}
}

There are possible values that could result in no value being returned, remember an if has an empty else{} whether you give it one or not, so lets look at one of your functions
boolean AND(boolean A, boolean B) {
if(A==true) {
if(B==true)
return true;
}else{
//else made explicit by me
//NO RETURN
}
}
else{
return false;
}
}
So if A was true but B was false nothing would be returned, the compiler cannot allow this
Its also unwise to use the multiline-braceless-if because it makes it easier to make these sorts of error. See http://cafe.elharo.com/blogroll/braceless-if-considered-harmful/

you must have a return statement for all possible "paths". For example
boolean AND(boolean A, boolean B) {
if(A==true) {
if(B==true)
return true;
}
else
return false;
}
is equivalent to
boolean AND(boolean A, boolean B) {
if(A==true) {
if(B==true)
return true;
else
//something must be returned here
}
else
return false;
}
You can also have a return null; statement at the end of every method to avoid this error.

Related

Execute code only if one of the if statements ran

Take a look at this example code.
boolean check = false;
if (condition) {
do x;
check = true;
}
else if (condition2) {
do y;
check = true;
}
else if (condition3) {
do z;
check = true;
}
if (check) {
do a;
} else {
do b;
}
There has to be a better way to do this than a boolean variable, no? I mean it works, but it looks kind of messy to me.
Logically, you could put a in each of the if conditions and add a single final else for b. Like,
if (condition) {
do x;
do a;
} else if (condition2) {
do y;
do a;
} else if (condition3) {
do z;
do a;
} else {
do b;
}
You could write it this way if you prefer:
if (condition) {
do x;
} else if (condition2) {
do y;
} else if (condition3) {
do z;
} else {
do b;
return;
}
do a;
Whether that makes sense for your context depends on what all these a, b, condition etc. actually are.
If you can't use return, you could at least reduce the number of places you're setting your boolean variable:
boolean check = true;
if (condition) {
do x;
} else if (condition2) {
do y;
} else if (condition3) {
do z;
} else {
do b;
check = false;
}
if (check) {
do a;
}
I would propose to define your business logic of actions x, y etc.. as separate classes or functional implementations of the interface Action with a single method execute()
Your codebase will be replaced with something similar:
#FunctionalInterface
public interface Action {
void execute();
}
Action action =
condition1 ? () -> System.out.println("Action X") :
condition2 ? () -> System.out.println("Action Y") : null;
if (Objects.nonNull(action)) {
action.execute();
((Action) () -> System.out.println("Action A")).execute();
} else {
((Action) () -> System.out.println("Action B")).execute();
}

Binary search tree String search

I have a program where I need to search for a specific word in a binary tree, the code I came up with for the search method for the string is not working. if someone could take a look at it I would greatly appreciate it.
I have tried a few alterations to this but it still did not work.
public boolean check(BSTNode t,String key){
if(!t.word.equals(key)){
check(t.left,key);
check(t.right,key);
}
else{
return true;
}
return false;
}
This could be written like this;
public boolean check(BSTNode t,String key) {
return
t.word.equals(key) || check(t.left,key) || check(t.right,key)
}
or, more verbosely;
public boolean check(BSTNode t,String key) {
if (t.word.equals(key)) return true;
if (check(t.left,key)) return true;
if (check(t.right,key)) return true;
return false;
}
You don't need a lot of else statements because the return statements stop execution in the function.
Edit:
You must also check to see that your BSTNode is not null, or you will get null pointer exceptions when you reach the end of the tree. This could be done at the start of the function, or before the inner recursive check calls:
public boolean check(BSTNode t,String key) {
if (t == null) return false;
if (t.word.equals(key)) return true;
if (check(t.left,key)) return true;
if (check(t.right,key)) return true;
return false;
}
or;
public boolean check(BSTNode t,String key) {
if (t.word.equals(key)) return true;
if (t.left != null && check(t.left,key)) return true;
if (t.right != null && check(t.right,key)) return true;
return false;
}

returning true with an occurance of a letter in a string?

it should return true as there is 'c' in the string S but it keeps returning False?
public class A {
public static void main(String[] args){
System.out.println(contains('c', "cccc"));
}
public static boolean contains(char c, String s) {
boolean to_return = true;
while(true) {
if(s.equals("")){
return to_return = false;
} else {
char c2 = s.charAt(0);
if(c==c2) {
to_return = true;
}
}
s=s.substring(1);
}
}
}
I have NO idea why it isnt? it only returns false if the string is empty which is clearly is(I am NOT allowed to use for loops etc..
you are not returning true anywhere in your code. So recursion happens till s.equals("") is evaluated to true and returns false.
Change
if(c==c2) {
to_return = true;
}
to
if(c==c2) {
return true;
}
works:
public static boolean contains(char c, String s) {
return s.indexOf(c) != -1;
}
If you want a loopy version, use a for loop like this, as it should be cleaner:
public static boolean contains(char c, String s) {
boolean to_return = true;
for(int i=0;i<s.length();i++) {
if(s.charAt(i) != c) {
to_return = false;
}
}
return to_return;
}
Alternatively, you can just do:
public static boolean contains2(char c, String s) {
return s.contains(String.valueOf(c));
}
Can you try a more cleaner method, it seems too cluttered.
public static boolean contains(char c, String s) {
if (s == null)
return false;
if (s.equals(""))
return false;
int size = s.length();
for (int i = 0; i < size; i ++) {
if(s.charAt(i) == c)
return true;
}
return false;
}

Long list of if comparisons in java

I need to compare two Objects. If there is a difference I need to log it corresponding to particular difference and return the true.
For example:
private boolean compTwoObjects(Object objA, Object ObjB) {
if(objA.getType() != objB.getType()) {
logTheDifference("getType is differing");
return true;
}
.
.
.
// Now this could invoke other composite methods
if(checkFont(objA.getFont(), objB.getFont()) {
logTheDifference("Font is differing");
return true;
}
}
private boolean checkFont(Font fontObjA, Font fontObjB) {
if(fontObjA.getBold() != fontObjB.getBold()) {
logTheDifference("font bold formatting differs");
return true;
}
.
.
.
if(fontObjA.getAllCaps() != fontObjB.getAllCaps()) {
logTheDifference("font all caps formatting differs");
return true;
}
.
.
.
if(checkBorderDiff(fontObjA.getBorder(), fontObjB.getBorder())) {
logTheDifference("border diff");
return true;
}
}
private boolean checkBorderDiff(Border borderObjA, Border borderObjB) {
if (borderObjA.getColor() != null || borderObjB.getColor() != null) {
if (!borderObjA.getColor().equals(borderObjB.getColor())) {
logIt("border color differing");
return true;
}
}
if (borderObjA.getDistanceFromText() != borderObjB.getDistanceFromText()) {
logIt("distance of the border from text or from the page edge in points differing");
return true;
}
if (borderObjA.isVisible() != borderObjB.isVisible()) {
logIt("border visibility differing");
return true;
}
if (borderObjA.getLineStyle() != borderObjB.getLineStyle()) {
logIt("line style differing for border");
return true;
}
if (borderObjA.getLineWidth() != borderObjB.getLineWidth()) {
logIt("border width in points differing");
return true;
}
if (borderObjA.getShadow() != borderObjB.getShadow()) {
logIt("border shadow differing");
return true;
}
}
//And it is going like this.
My problem is I want to avoid multiple if statements in the methods. Also I want to log the messages corresponding to particular difference.
I have read few similar type of problems on stackoverflow solved either by command pattern or HashMap. But they don't include comparisons in that.
I want to refactor my code to get rid of series of if's.
Have a system of comparators, backed by generics. Every comparer will also know what is next in line. For example:
interface IComparer<T> {
boolean areDifferent (T first, T second);
}
class FontComparer implements IComparer<Font> {
#Override
public boolean areDifferent(Font first, Font second) {
// Compare fonts start
// ..
// Compare fonts end
return new BorderComparer().areDifferent(first.getBorder(), second.getBorder());
}
}
class BorderComparer implements IComparer<Border> {
#Override
public boolean areDifferent(Border first, Border second) {
//Do border comparison alone
return false;
}
}
You could setup a comparer chain now, and bail out when comparison fails. Otherwise, comparison goes to the comparer next in the chain.
The client code will finally look like:
Object one = new Object();
Object two = new Object();
new ObjectComparer().areDifferent(one, two);
Have you considered enums?
private enum FontCmp {
Bold {
#Override
boolean cmp(Font a, Font b) {
return a.getBold() != b.getBold();
}
},
AllCaps {
#Override
boolean cmp(Font a, Font b) {
return a.getAllCaps() != b.getAllCaps();
}
},
Border {
#Override
boolean cmp(Font a, Font b) {
return BorderCmp.compare(a.getBorder(), b.getBorder());
}
};
// Each enum has one of these.
abstract boolean cmp(Font a, Font b);
// Compare them all and log any failures.
static boolean compare(Font a, Font b) {
for (FontCmp c : FontCmp.values()) {
if (c.cmp(a, b)) {
logIt("FontCmp-" + c + " failed");
return false;
}
}
return true;
}
}
You could also use reflection as described here. Also look into introspection as described here
Fundamentally you are trying to do a series of comparisons, so there is little choice but to do a series of comparisons.
What you could do is define an interface/enum/abstract class which is a FieldChecker. That FieldChecker would have an abstract method implemented differently in each FieldChecker:
String performCheck(Font a, Font b) {
if (DO CHECK HERE) {
return "failure message";
}
return null;
}
Then your check function just becomes:
for (FieldChecker fc: fieldCheckers) {
String res = fc.performCheck(a,b);
if (res != null) {
return res;
}
}
return "All ok";

Exception in thread "main" StackoverFlow error

I am writing a program that verifies if a password meets the appropriate requirements. I have all of my code written, and I feel it should work, but I get the following error:
Exception in thread "main" java.lang.StackOverflowError
at java.lang.String.length(String.java:623)
at PasswordVerifier.isValid(PasswordVerifier.java:5)
at PasswordVerifier.isValid(PasswordVerifier.java:6)
and then it repeats the last line of the error for quite some time. I've been looking around and cannot seem to figure out my issue. I know something is continually looping that I don't want to, but the fix eludes me. Here is my code
public class PasswordVerifier{
private static int MIN_PASSWORD_LENGTH = 6;
public static boolean isValid(String str){
if (str.length() >= MIN_PASSWORD_LENGTH){
if (PasswordVerifier.isValid(str) == true){
if (PasswordVerifier.hasUpperCase(str) == true){
if (PasswordVerifier.hasLowerCase(str) == true){
if (PasswordVerifier.hasDigit(str) == true){
return true;
}
}
}
}
}
return false;
}
private static boolean hasUpperCase(String str){
for (char c : str.toCharArray()){
if (Character.isUpperCase(c)){
return true;
}
}
return false;
}
private static boolean hasLowerCase(String str){
for (char c : str.toCharArray()){
if (Character.isLowerCase(c)){
return true;
}
}
return false;
}
private static boolean hasDigit(String str){
for (char c : str.toCharArray()){
if (Character.isDigit(c)){
return true;
}
}
return false;
}
}
Any help would be appreciated!
public static boolean isValid(String str){
// ...
if (PasswordVerifier.isValid(str) == true){
// ...
}
// ...
}
You're calling isValid(String) from within itself, which is causing the infinite loop recursion.
I'm going to take a wild guess and say this is what you want instead:
public static boolean isValid(String str){
if (str.length() >= MIN_PASSWORD_LENGTH){
// Removed call to .isValid(String)
if (PasswordVerifier.hasUpperCase(str)){
if (PasswordVerifier.hasLowerCase(str)){
if (PasswordVerifier.hasDigit(str)){
return true;
}
}
}
}
return false;
}

Categories