Problem with scoped local variables and conditionals
Question
I am trying to construct method which returns a boolean:
public boolean isStringValid(String s){
boolean isValid;
String temp = null;
// only combinations of 'A','B','C' are allowed
for (int i = 0; i < s.length(); i++)
{
temp = s.substring(i, i+1);
if (temp.equals("A")|temp.equals("B")|temp.equals("C")){
isValid= true;
}else{
isValid= false;
}
}
return isValid;
}
But I get a compiler error saying "the local variable isValid may not have been initialized".
What I am trying to do is take a string and examine its every letter, if any letter other than A, B or C is found in the string, the isStringValid method should return a false. Only after every letter is checked and found to be either A,B or C can the method return true.
I guess I am having trouble figuring out the scope of the local variables. What is the appropriate way for the method to return from within the if/else blocks? If that is not possible, what would you recommend is the best way to design this?
Thank you in avdance Kindest regards
Solution
I agree with the answers that state that you should initialize the isValid boolean variable.
However, you could do what you want with a regular expression
/*
* returns false if s contains a character different from 'a' 'b' or 'c'
*/
public boolean isStringValid(String s){
return !Pattern.matches("($^|[^abc]+)",s);
}
[abc] means that you are checking if s contains the 'a','b' or 'c' character
[^abc] means that you are checking if s contains a character that´s none of 'a','b' or 'c'.
[^abc]+ means that you are checking if s contains at least one character that´s none of 'a','b' or 'c'.
$^ Means empty strings
OTHER TIPS
What happens if you get an empty string as argument?
The compiler needs to be sure you're always returning something. Initialize your isValid variable with false, this way if the method gets an empty string it would just return the default value.
boolean isValid = false;
In Java you can't return a variable that may not be initialized, just be sure in all possible flows the variable is set with any value.
UPDATE: This will solve your question but I suggest you to take a look to the answers below because your method's logic isn't correct
Perhaps the for may actually not loop. so isValid is not set.
The method is wrong (besides the compiler error, which Victor explained). If the last letter is C and everything else is D it will return true. Also, you should use char, and you need two bars (||) for logical or. Try:
public boolean isStringValid(String s){
// only combinations of 'A','B','C' are allowed
for (int i = 0; i < s.length(); i++)
{
char tempChar = s.charAt(i);
if (!(tempChar == 'A'
|| tempChar == 'B'
|| tempChar == 'C'))
return false;
}
return true;
}
If you want to return false for empty strings, do that up in the beginning:
if(s.length() == 0)
return false;
The variable isValid
is a local variable. In the Java Language spec:
A local variable (§14.4, §14.13) must be explicitly given a value before it is used, by either initialization (§14.4) or assignment (§15.26), in a way that can be verified by the compiler using the rules for definite assignment.
See section 4.5.5 Initial Values of Variables in the Java Language Specification:
http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html
Initialise the variable to false to start off with and then only set it to true in the correct part of your method, i.e. here:
if (temp.equals("A")|temp.equals("B")|temp.equals("C")){
isValid = true;
}
Remove the else statement and let the method return as normal.
Note that your loop will only return true or false depending on the last char in your string. What you want to do is something like
public boolean isStringValid(String s) {
for (char c : s.toCharArray()) {
if (!('A' == c || 'B' == c || 'C' == c)) {
return false;
}
}
return true;
}