UPDATE:
The final version of my utility looks like this:
StringBuilder b = new StringBuilder();
for(char c : inLetters.toLowerCase().toCharArray())
{
switch(c)
{
case '0': b.append("0"); break;
case '1': b.append("1"); break;
case '2': case 'a': case 'b': case 'c': b.append("2"); break;
case '3': case 'd': case 'e': case 'f': b.append("3"); break;
case '4': case 'g': case 'h': case 'i': b.append("4"); break;
case '5': case 'j': case 'k': case 'l': b.append("5"); break;
case '6': case 'm': case 'n': case 'o': b.append("6"); break;
case '7': case 'p': case 'q': case 'r': case 's': b.append("7"); break;
case '8': case 't': case 'u': case 'v': b.append("8"); break;
case '9': case 'w': case 'x': case 'y': case 'z': b.append("9"); break;
}
}
return builder.toString();
ORIGINAL QUESTION:
I'm taking on the simple task of converting an alphanumeric phone number to a string of digits. For example, 1-800-HI-HAXOR would become 1-800-44-42967. My initial attempt was to create a nasty switch statement, but I'd love a more elegant, and efficient solution. Here's what I've got:
for(char c : inLetters.toLowerCase().toCharArray())
{
switch(c)
{
case '0': result+="0"; break;
case '1': result+="1"; break;
case '2': case 'a': case 'b': case 'c': result+="2"; break;
case '3': case 'd': case 'e': case 'f': result+="3"; break;
case '4': case 'g': case 'h': case 'i': result+="4"; break;
case '5': case 'j': case 'k': case 'l': result+="5"; break;
case '6': case 'm': case 'n': case 'o': result+="6"; break;
case '7': case 'p': case 'q': case 'r': case 's': result+="7"; break;
case '8': case 't': case 'u': case 'v': result+="8"; break;
case '9': case 'w': case 'x': case 'y': case 'z': result+="9"; break;
}
}
Thanks!
The switch statement is not really that bad. Your algorithm is linear with respect to the length of the phone number. The code is readable and pretty easy to verify by inspection. I wouldn't mess with it, except to add a default case for handling errors. (I'm not a Java programmer, so forgive me if it's called something else.)
If you have to make it faster, a pre-initialized table indexed by character would avoid any comparisons beyond basic error checking. You could even avoid the case conversion by duplicating the values in the table (digit['A'] = digit['a'] = "2";). The cost of initializing the table would be amortized over the total number of conversions.
You could do this using the Apache Commons Lang StringUtils, as follows:
String output = StringUtils.replaceChars(StringUtils.lowerCase(input),
"abcdefghijklmnopqrstuvwxyz",
"22233344455566677778889999");
Assuming speed is not your main concern, of course, and you want a compact solution ;)
Use a Map, where the keys are the letters and digits, and the value is the number on the keypad. (So each keypad number will be indexed by three or four letters and one digit).
Map<Character, Character> keypad = new HashMap<Character, Character>();
...
StringBuilder buf = new StringBuilder(inLetters.length());
for (int idx = 0; idx < inLetters.length(); ++idx) {
Character ch = keypad.get(inLetters.charAt(idx));
if (ch != null)
buf.append(ch);
}
Update: I was curious whether a hand-coded lookup table would perform better than a dense set switch cases. In my casual testing, I found the following code to be the fastest I could come up with:
private static final char[] lut =
"0123456789:;<=>?#22233344455566677778889999[\\]^_`22233344455566677778889999".toCharArray();
private static final char min = lut[0];
String fastest(String letters)
{
int n = letters.length();
char[] buf = new char[n];
while (n-- > 0) {
int ch = letters.charAt(n) - min;
buf[n] = ((ch < 0) || (ch >= lut.length)) ? letters.charAt(n) : lut[ch];
}
return new String(buf);
}
Surprisingly, it was more than twice as fast as similar code using a switch statement (which compiled to a tableswitch instruction). This was just for fun, mind you, but on my laptop, running in a single thread, I could convert 10 million 10-letter-"numbers" in about 1.3 seconds. I was really surprised, because as I understand it, a tableswitch operates in essentially the same way, but I expected it to be faster since it is a JVM instruction.
Of course, unless I were getting paid only for each of a limitless supply of phone numbers I could convert, I would never write code like this. A switch is much more readable, performs well as-is, and is likely to get a free performance boost in some future JVM.
Far and away, the greatest improvement to the original code comes from using a StringBuilder instead of concatenating strings, and that does nothing to impair readability of the code. Using charAt instead of converting the input to a char[] also makes the code simpler and easier to understand and improves performance too. Finally, appending char literals instead of String literals ('1' rather than "1") is a performance improvement that aids readability a little too.
How about simply:
String convert(String inLetters) {
String digits = "22233344455566677778889999";
String alphas = "abcdefghijklmnopqrstuvwxyz";
String result = "";
for (char c : inLetters.toLowerCase().toCharArray()) {
int pos = alphas.indexOf(c);
result += (pos == -1 ? c : digits.charAt(pos));
}
return result;
}
If you want a solution that doesn't force you to enumerate all of the letters, you could do something like:
char convertedChar = c;
if (Character.isLetter(c)) {
//lowercase alphabet ASCII codes: 97 (a)-122 (z)
int charIndex = ((int)c) - 97;
//make adjustments to account for 's' and 'z'
if (charIndex >= 115) { //'s'
charIndex--;
}
if (charIndex == 121) { //'z'-1
charIndex--;
}
convertedChar = (char)(2 + (charIndex/3));
}
result += convertedChar;
If you run this 10^9 times in a tight loop and ctrl-break it a few times, my bet is that nearly every time it will be deep in the string class trying to accomplish one of those innocent-looking "+=" operators.
Switch statements get compiled to a similar form as if-else statements, (each case statement is essentially an if (c == '...') test in disguise) so although this is visually more compact than cascading if's that test for each character, there may or may not be any real performance benefit.
You can potentially streamline it by eliminating some of the comparisons. The key is that char is an integer type (which is why you can switch on a char) so you can use numeric comparison operators. and 'aAssuming your inLetters string only contains alphanumeric characters, this should work... (All other characters will pass through unchanged.)
String result = "";
for (char c : letters.toLowerCase().toCharArray()) {
if (c <= '9') result += c;
else if (c <= 'c') result += "2";
else if (c <= 'f') result += "3";
else if (c <= 'i') result += "4";
else if (c <= 'l') result += "5";
else if (c <= 'o') result += "6";
else if (c <= 's') result += "7";
else if (c <= 'v') result += "8";
else if (c <= 'z') result += "9";
else result += c;
}
The characters of interest have the hexadecimal values: '0' = 0x30, '9' = 0x39, 'a' = 0x61, and 'z' = 0x7a.
Edit: It's better practice to use a StringBuilder and append() to create the string, but for small strings it's not likely to be appreciably faster. (Amdahl's Law demonstrates that the actual speedup you can expect from optimizing code is limited by the percentage of time actually spent in that code.) I only used concatenated strings to make the algorithm clear to the OP.
Related
This question already has answers here:
In a switch statement, why are all the cases being executed?
(8 answers)
Closed last year.
I am working on the game where the columns of the board are represented by the characters but i would like to assign them an index.
I have decided to use the switch statement in that case, however it does produce the wrong result.
With the current code I attach, it gives me 14 as an index, however since the string is 7h, and it takes h as a char, it should give an index of 7. What Could be an issue? Thanks in advance!
public class Check {
public int columnToInt(char c) {
int index=0;
switch(c) {
case 'a':
index=0;
case 'b':
index=1;
case 'c':
index=2;
case 'd':
index=3;
case 'e':
index=4;
case 'f':
index=5;
case 'g':
index=6;
case 'h':
index=7;
case 'i':
index=8;
case 'j':
index=9;
case 'k':
index=10;
case 'l':
index=11;
case 'm':
index=12;
case 'n':
index=13;
case 'o':
index=14;
}
return index;
}
public static void main(String[] args) {
String myStr = "7h";
char c =myStr.charAt(1);
System.out.println("the char at position 1 is "+c);
Check check = new Check();
int result = check.columnToInt(c);
System.out.println(result);
}
}
Java switch statements can be a bit annoying to use. You need to use break or all the cases after the expected one will be executed as well.
switch(c) {
case 'a':
index=0;
break;
Alternatively you can use a return.
switch(c) {
case 'a':
return 0;
You must add the break keyword for each case.
For example:
case 'a':
index=0;
break;
otherwise next assignments are applied.
I am working on a rather unique coding situation in Java. The purpose of the program I am trying to write is to take an Amateur Radio call sign, convert the letters in the call sign into numbers as defined by a list or other structure, treat the number as its face integer value, and run these numbers through several mathematical operations to output a unique "User Code" at the end. The length of characters, as well as the number itself, will vary from user to user based on their call sign, which is fine. The biggest obstacle I have encountered is that I do not want the letters to be assigned values in a 1-26 or 0-25 type pattern. I will post my code in a moment to show you. For the moment, the end use of this User Code is unimportant to this example, but suffice it to say that since I will be the only one using this particular code example I am not very concerned with doing validity checks or the like as I will ensure the integrity of the input data manually. With this being said, I do have a working solution which I will post here, but my question is not "it doesn't work" because it does work, my problem is that it is, in my opinion, bloated, and something tells me it could be cut down considerably. Here is the code, and following are some alternatives I considered but rejected:
import java.util.*;
import java.io.*;
public class UserCode
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int baseNumber = 0;
int finalNumber;
String callSign;
System.out.println("Enter CallSign for Code Generation: ");
callSign = in.nextLine();
String s = callSign.toUpperCase();
for (int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
if (Character.isDigit(c))
{
int l = Character.getNumericValue(c);
baseNumber = baseNumber + l;
}
else if (Character.isLetter(c))
{
int letNum = 0;
switch (c)
{
case 'A':
letNum = 23;
break;
case 'B':
letNum = 17;
break;
case 'C':
letNum = 5;
break;
case 'D':
letNum = 11;
break;
case 'E':
letNum = 34;
break;
case 'F':
letNum = 18;
break;
case 'G':
letNum = 13;
break;
case 'H':
letNum = 31;
break;
case 'I':
letNum = 27;
break;
case 'J':
letNum = 25;
break;
case 'K':
letNum = 7;
break;
case 'L':
letNum = 25;
break;
case 'M':
letNum = 33;
break;
case 'N':
letNum = 26;
break;
case 'O':
letNum = 28;
break;
case 'P':
letNum = 16;
break;
case 'Q':
letNum = 14;
break;
case 'R':
letNum = 2;
break;
case 'S':
letNum = 4;
break;
case 'T':
letNum = 6;
break;
case 'U':
letNum = 8;
break;
case 'V':
letNum = 10;
break;
case 'W':
letNum = 37;
break;
case 'X':
letNum = 12;
break;
case 'Y':
letNum = 3;
break;
case 'Z':
letNum = 1;
break;
default:
System.out.println("Call Contains a bad character. Try again. \n");
}
baseNumber = baseNumber + letNum;
}
}
System.out.println("\n");
String baseStr = Integer.toString(baseNumber);
System.out.println("The Base number is: " + baseStr + "\n");
int sMod = baseNumber%7;
String sModStr = Integer.toString(sMod);
System.out.println("The Check Digit is: " + sModStr + "\n");
String combine = baseStr + sModStr;
int nextOp = Integer.parseInt(combine);
finalNumber = nextOp * nextOp;
String finalStr = Integer.toString(finalNumber);
System.out.println("The User Code is: " + finalStr + "\n");
}
}
Okay, as I said this code works, but it is long. I had considered a few alternatives, none of which will really work. The first was Enum, but that obviously is outside my parameters as it produces a 1-26 incremented pattern. There are several variations of this using various for{} loops but the result there is the same. I even considered a new HashMap and map.put statements, but that's only marginally shorter and it would seem to me that creating a hashmap would, in the end, actually use more memory than my current solution. As you can see, I did not .split or use .toCharArray() since these created separate entities in memory that I did not need. All the information I needed was already contained in the string itself, except for my chosen numerical values. Finally, I could have created another class file with this assignment code, but the result is the same: the length itself hasn't been changed it's been spread over two files (and actually increased in calling the method).
Having put this out here, can anyone see any way I can shorten this code, particularly in the area of the switch{} block and still retain the same result with the same numerical values? I would be highly interested in any suggestions that can be made in this regard. BTW I didn't mention this but this is not a school assignment, this is a personal project, though my level of Java knowledge is about at that of a beginner taking my first Java class LOL. Thanks
if you want to stick with this logic then use a HashMap<Character, Integer> and setup only once the values like: map.put('Z', 1); and so on, then u don't need the switch. You can get the values by using: map.get('Z'); which will return every time 1
it is easy to implement and easy to change the code if needed
Create an array of corresponding integers:
int[] letnums = {23, 17, 5, ... };
char c = s.charAt(i);
if (Character.isLetter(c)) {
int letnum = letnums(c);
...
}
So i have created this code to convert words into phone numbers, but when i try to run this code with letters under 7 word it will display string index out of range. But 7 or more is fine. How do i fix this? If so how do i set the string range?
{
System.out.println("Enter a word to be converted: ");
String telLetter = console.next ();
telLetter = telLetter.toUpperCase();
String telNumber="7";
int count=0;
int i=0;
while(count <7)
{switch(telLetter.charAt(i))
{case 'A':case 'B':case 'C': case 'a': case 'b': case 'c':
telNumber += "2";
count++;
break;
case 'D':case 'E':case 'F': case 'd': case 'e': case 'f':
telNumber += "3";
count++;
break;
case 'G':case 'H':case 'I': case 'g': case 'h': case 'i':
telNumber += "4";
count++;
break;
case 'J':case 'K':case 'L': case 'j': case 'k': case 'l':
telNumber += "5";
count++;
break;
case 'M':case 'N':case 'O': case 'm': case 'n': case 'o':
telNumber += "6";
count++;
break;
case 'P':case 'R':case 'S': case 'p': case 'r': case 's':
telNumber += "7";
count++;
break;
case 'T':case 'U':case 'V': case 't': case 'u': case 'v':
telNumber += "8";
count++;
break;
case 'W':case 'X':case 'Y':case 'Z': case 'w': case 'x': case 'y': case 'z':
telNumber += "9";
count++;
break;
}
if( count==3) {
telNumber += "-";
}
i++;
}
System.out.println( telNumber );
}
}}
Fixes in code:
Use while(count < telLetter.length()) in place of while(count <7)...
telLetter.charAt(i) can be removed by (telLetter.charAt(count))... By doing this you don't need to create an extra variable int i = 0;... Its a good practice to keep variable minimum.
Use a scanner to get the input... Like.. Scanner sc = new Scanner(System.in); String telLetter = sc.next();...
After you used your resources do close them by using sc.close();....
Also i can see that you are appending 7 at the begining of every number... if that's a requirement then its ok.. other wise you can use... String telNumber="";
I would recommend using StringBuilder because in one object you can do it all.. While appending a character every time in string you are continuously creating a new string and giving it the reference of telNumber.
Also in your code either remove telLetter = telLetter.toUpperCase(); or remove the cases with lowercase alphabets.. because on making toUpperCase() you are just writing extra lines by writing cases for lowercase characters that are not needed...
System.out.println("Enter a word to be converted: ");
Scanner scan=new Scanner(System.in);
String telLetter = scan.next ();
int stringLength=telLetter.length();
telLetter = telLetter.toUpperCase();
String telNumber="7";
while(count <stringLength)
{
switch(telLetter.charAt(count))
Change your code like this.
But as per your code, the 7 is always prefixed in the converted phone number.
String telNumber=""; telNumber should be declared with empty string.
while(count <7)
Your code won't end until it has run through 7 characters. Try using while(count < telLetter.length())
Your while loop condition needs to check for the length of the telLetter string.
while (count <7 && count < telLetter.length())
As a part of my implementation I need to implement iterating over chars as efficient as possible. Here is a part of my source code that I wrote:
public int normalize(char s[], int len) {
for (int i = 0; i < len; i++) {
switch (s[i]) {
//numbers
case EN_D0:
case AR_D0:
s[i]= FA_D0;
break;
case EN_D1:
case AR_D1:
s[i]= FA_D1;
break;
case EN_D2:
case AR_D2:
s[i]= FA_D2;
break;
case EN_D3:
case AR_D3:
s[i]= FA_D3;
break;
case EN_D4:
case AR_D4:
s[i]= FA_D4;
break;
case EN_D5:
case AR_D5:
s[i]= FA_D5;
break;
case EN_D6:
case AR_D6:
s[i]= FA_D6;
break;
case EN_D7:
case AR_D7:
s[i]= FA_D7;
break;
case EN_D8:
case AR_D8:
s[i]= FA_D8;
break;
case EN_D9:
case AR_D9:
s[i]= FA_D9;
break;
//Symboles
case EN_QUESTION_MARK:
s[i]=FA_QUESTION_MARK;
break;
case EN_PERCENT_SIGN:
s[i]=FA_PERCENT_SIGN;
break;
case EN_DASH1:
case EN_DASH2:
case EN_DASH3:
case EN_DASH4:
s[i]=FA_DASH;
break;
case HAMZA_ABOVE:
len = delete(s, i, len);
i--;
break;
default:
break;
}
}
return len;
What is the most efficient way of doing such process? Please consider that I did not put all the conditions here because of it was around 600 different conditions. In addition to consider that this part of code should be run for huge documents that have tremendous amount of chars. So the efficiency really matters.
If all the constants in your case statements and assignments are chars, you can use an array to map source char to target char. The length of the array would be 2^16.
char[] map = new char[65536];
...
map[AR_D7] = FA_D7;
...
map[AR_D9] = FA_D9;
...
Then you loop becomes :
for (int i = 0; i < len; i++)
s[i] = map[s[i]];
how come this java switch statement keeps telling me my statements are not statements
public void setConstant(float inNumGrade)
{
this.yourNumberGrade = inNumGrade;
switch (this.yourLetterGrade)
{
case 'A':
this.yourNumberGrade >= 0.90;
break;
case 'B':
this.yourNumberGrade >= .8;
break;
case 'C':
this.yourNumberGrade >= .7;
break;
case 'D':
this.yourNumberGrade >= .6;// not a statement
default:
} // end switch
}
I see what you are trying to do, but I think you are going around it the wrong way. What it seems like you are trying to do, is set the "letter grade" based on the switch, not the number grade! I think what you are really trying to do is this:
public void setGrades(float inNumGrade)
{
this.yourNumberGrade = inNumGrade;
if( this.yourNumberGrade >= 0.90)
this.yourLetterGrade = 'A';
else if(this.yourNumberGrade >=0.80)
this.yourLetterGrade = 'B';
else if (this.yourNumberGrade >=0.70)
this.yourLetterGrade= 'C';
else if (this.yourNumberGrade >=0.60)
this.yourLetterGrade= 'D';
else
this.yourLetterGrade= 'F';
}
You cannot switch on ranges in Java. If you want to do this with a switch, you'd have to do a switch(true), and then do case this.yourNumberGrade>=0.90:
As I expected, you misunderstand how a switch works. If you REALLY need to do this via switch(if/else/else if is better), you'd have to do it this way:
public void setGrades(float inNumGrade)
{
this.yourNumberGrade = inNumGrade;
switch(true)
{
case this.yourNumberGrade >= 0.90:
this.yourLetterGrade = 'A';
break;
case this.yourNumberGrade >=0.80:
this.yourLetterGrade = 'B';
break;
case this.yourNumberGrade >=0.70:
this.yourLetterGrade= 'C';
break;
case this.yourNumberGrade >=0.60:
this.yourLetterGrade= 'D';
break;
default:
this.yourLetterGrade= 'F';
break;
}//end switch
}
Because this.yourNumberGrade >= .6; isn't a valid statement like the compiler is telling you. This would be a valid statement:
b = this.yourNumberGrade >= .6;
-- or --
this.yourNumberGrade = .6;
It depends on what you are trying to accomplish.
What exactly are you trying to do? >= is comparison NOT assignment that is why you get the error...just remove > in all places.
Eric explained nicely how to do what you seem to be trying to accomplish, but let me clear up where you went wrong.
A switch/case structure compares a given variable (the switch argument) to possible values (the case arguments) and then executes the code between the matching case statement and the next break statement (or, if the language does not support fall-through, before the next case statement).
What you're trying to do is not to compare a variable to constant expressions, but to compare a variable against conditions. An if/elseif structure would probably be a cleaner way to express it:
if (this.yourNumberGrade >= 0.90) {
this.yourLetterGrade = 'A';
} else if (this.yourNumberGrade >= 0.80) {
this.yourLetterGrade = 'B';
} else if (this.yourNumberGrade >= 0.70) {
this.yourLetterGrade = 'C';
} else if (this.yourNumberGrade >= 0.60) {
this.yourLetterGrade = 'D';
} else { // you left the default out, but I assume this will be an F for Failed
this.yourLetterGrade = 'F';
}
If you want it shorter, you could try experimenting with the ternary operator like so:
this.yourLetterGrade = (
this.yourNumberGrade >= 0.90 ? 'A' : (
this.yourNumberGrade >= 0.80 ? 'B' : (
this.yourNumberGrade >= 0.70 ? 'C' : (
this.yourNumberGrade >= 0.60 ? 'D' : 'F'
)
)
)
)
As you can see, this costs you a LOT of readability, so if/else is probably the cleanest way to do it.
What Eric was trying to show you is a structure like this:
switch (true) { // We compare the boolean constant "true" to the case arguments
case this.yourNumberGrade >= 0.90:
// this is a boolean expression and evaluates either
// to "true" (matches the switch argument) or
// to "false" (does not match the switch argument)
this.yourLetterGrade = 'A';
break;
case this.yourNumberGrade >= 0.80:
this.yourLetterGrade = 'B';
break;
case this.yourNumberGrade >= 0.70:
this.yourLetterGrade = 'C';
break;
case this.yourNumberGrade >= 0.90:
this.yourLetterGrade = 'D';
break;
default:
// This is executed if none of the case arguments evaluate
// to the value of the switch argument.
this.yourLetterGrade = 'F';
// No break needed, because the end of the switch structure follows:
}
I hope that clears it up for you. You probably have to pay more attention to the exact semantics of the structures you are trying to use. These structures are very similar in most languages.
For kicks and giggles, you could even do it with an array:
// Our letter grades in ascending order (from bad to good).
String letterGrades[] = {'F','D','C','B','A'};
// Our number grade is in the range [0.0;1.0]. As floating point numbers are
// too precise for indexes, we want to round them down to the cut-off
// (0.9, 0.8, etc) and turn them into integer values we can use as array indices.
int gradeIndex = (int) Math.floor(this.yourNumberGrade*10);
// The lowest cut-off is 0.6, so we can treat everything lower than that the same
gradeindex = gradeindex - 5;
gradeIndex = Math.max(gradeIndex, 0);
// With Math.max we have ensured that no index can be lower than 0, now we need
// to make sure that no index is larger than the largest index in our array
// (which by definition is equal to the array's length (i.e. number of elements)
// minus 1 (because the lowest index is 0, an array of e.g. size 4 has the
// indices 0,1,2,3, but lacks an index 4 -- better get used to it, that's how
// programmers count, too).
gradeIndex = Math.min(gradeIndex, letterGrades.length-1);
// Now that our index is clean and guaranteed to be within range, we can use it
// to look up the letter grade:
this.yourLetterGrade = letterGrades[gradeIndex];
Without comments and with a few shorthands, this is even shorter:
// Grades are as follows: A: 90%+, B: 80%+, C: 70%+, D: 60%+, F: <60%
String letterGrades[] = {'F','D','C','B','A'};
int gradeIndex = Math.min(
Math.max(0, (int) Math.floor(this.yourNumberGrade*10) - 5),
letterGrades.length-1
);
this.yourLetterGrade = letterGrades[gradeIndex];
Note that this makes, however, less clear, where the exact cut-off points for the letter grades are, which is why it needs comments. Also, you'll have a problem if the cut-offs change for any reason (e.g. A: 85%+ or F: <66.6%). You could still adjust the calculation (the Math.floor(this.yourNumberGrade*10)-5 part), but this will make it even harder to follow and won't help if the grades aren't merely gradual. For traditional systems, however, it's a quick and easy way to do it.
You are only doing a comparison which isn't a valid statement in this context.
You probably mean to do an assignment
replace ">=" with "=" if that's what you want to accomplish.
The problem is that you are making a comparison and not assigning the the value. Perhaps you could do something like this:
public void setConstant(float inNumGrade)
{
this.yourNumberGrade = inNumGrade;
switch (this.yourLetterGrade)
{
case 'A':
this.yourNumberGrade = 0.90;
break;
case 'B':
this.yourNumberGrade = .8;
break;
case 'C':
this.yourNumberGrade = .7;
break;
case 'D':
this.yourNumberGrade = .6;
default:
} // end switch
}
This would actually assign the value to "yourNumberGrade. However this would only be the lower limit of the grade. It might be better to make it where you substitute the "yourNumberGrade" for "yourLetterGrade" and have it determine the letter grade based on the number grade...
You must add a break; inside of each case block.
switch(this.grade){
case 'A':
System.out.println("You got an A");
break;
default:
System.out.println("INVALID GRADE");
break;}