Can someone explain to me, how my method here in java that expects a int, but accepts '!' as an argument? further more, how can it interpet it as 33 when i debug it, but when i do System.out.println(Character.getNumericValue('!')); it prints -1?
here is the code guys:
public abstract class Stuff {
public static char getCharacterFromNumber(int number) throws InvalidCharException {
if(number>=20) {
if (number <= 45) {
switch (number) {
case 20:
return 'a';
case 21:
return 'b';
case 22:
return 'c';
case 23:
return 'd';
case 24:
return 'e';
case 25:
return 'f';
case 26:
return 'g';
case 27:
return 'h';
case 28:
return 'i';
case 29:
return 'j';
case 30:
return 'k';
case 31:
return 'l';
case 32:
return 'm';
case 33:
return 'n';
case 34:
return 'o';
case 35:
return 'p';
case 36:
return 'q';
case 37:
return 'r';
case 38:
return 's';
case 39:
return 't';
case 40:
return 'u';
case 41:
return 'v';
case 42:
return 'w';
case 43:
return 'x';
case 44:
return 'y';
case 45:
return 'z';
}
}
}
throw new InvalidCharException();
}
public static void main(String [] args){
try {
System.out.println(Stuff.getCharacterFromNumber('!'));
} catch (InvalidCharException e) {
e.printStackTrace();
}
System.out.println(Character.getNumericValue('!'));
}
}
i have searched but havent found anything similar to my problem, and if someone has a better idea for the title i'd appricate it :)
Character literals are nothing more than pure values, but with different types. 48 represents exactly the same value as '0' (though the first one is of a type int and the second one is of a type char). 49 also represents the same value as '1'. That's why 'a' + 1 will result in a value equal to 'b'.
What you are confused about is why this:
System.out.println(Character.getNumericValue('!'));
prints -1. Well, to find out why, let's jump into java docs. We can see that the method Character.getNumericValue:
Returns the int value that the specified character (Unicode code point) represents.
It does not return the Unicode value of a character. If you want to see what number represents the character literal '!' you might want to do it like so:
System.out.println((int)'!');
Which will print: 33.
The character '!' has an ASCII value of 33. Java allows for a char value to be widened to an int, which explains why you can pass a char into a method expecting an int.
However, Character.getNumericValue does something different.
Returns the int value that the specified Unicode character represents.
(bold emphasis mine)
That is '1' returns 1, whereas the ASCII code is 49. If the character doesn't represent a numeric value:
If the character does not have a numeric value, then -1 is returned.
You get 2 different values because the ASCII code and the numeric value are two different concepts.
Related
I am working with an Android app, and I want to print out a HashMap's keys and values in a certain manner. Let's say the following are the contents of the HashMap:
11: 000010
12: 102643
24: 877
3: 990000
h: 6008770000
m: 0800
I want to print out the HashMap keys and values in such a way that the keys with letters should be printed first alphabetically, followed by the numeric keys in ascending order:
h: 6008770000
m: 0800
3: 990000
11: 000010
12: 102643
24: 877
What I am doing right now is:
Get the key set and save it to an ArrayList
Sort the ArrayList using a comparator
Print out the values in the map by using the sorted list
Here's my code:
List<String> keyList = new ArrayList<>(requestMap.keySet());
Collections.sort((keyList), comparator);
for(String key : keyList) {
Log.d(key, requestMap.get(key));
}
Comparator<String> comparator = (o1, o2) -> {
if (o1 == null) return -1;
else if (o2 == null) return 1;
if(TextUtils.isDigitsOnly(o1) && TextUtils.isDigitsOnly(o2)) {
return Integer.compare(Integer.parseInt(o1), Integer.parseInt(o2));
}
if(!TextUtils.isDigitsOnly(o1)) {
return -1;
} else {
return o1.compareTo(o2);
}
};
It's so far working, but for some cases I don't get the desired order. For example, for a specific Map I always get the following result:
3: 005000
4: 000000058985
12: 095508
22: 022
h: 6008770000
m: 0221
11: 000004
13: 0120
24: 877
25: 00
35: 77690088000000131D20077100000F
37: QWERTY123456
41: 00000003
42: 100000004000000
48: 456789123451 0000050201
60: 000001
61: 0201020000000045000000000300000000000015000102000000049770000000049770000000001659
I made the comparator with the idea that the alphabetical strings should be sorted first, followed by the numeric strings, but right now I'm having doubts if my logic for the comparator is correct. Can anyone point me in the right direction?
if(TextUtils.isDigitsOnly(o1) && TextUtils.isDigitsOnly(o2)) {
return Integer.compare(Integer.parseInt(o1), Integer.parseInt(o2));
}
So the case where both are digits only is dealt with.
if(!TextUtils.isDigitsOnly(o1)) {
return -1;
This is the case where the first has non-digits. This is return -1 even if the second has non-digits. When both have non-digits we should be comparing.
} else {
return o1.compareTo(o2);
This is the case where the first is digits, so don't want to compare. Because we have excluded both are digits only, the second must be non-digits (though we shouldn't be comparing).
}
So, it looks like you certainly want to remove the !!
You should probably also cover all cases. Either have a condition whether you should cover the compare case
!TextUtils.isDigitsOnly(o1) && !TextUtils.isDigitsOnly(o2)
or nest
if (TextUtils.isDigitsOnly(o1)) {
if (TextUtils.isDigitsOnly(o2)) {
...
} else {
...
}
} else {
if (TextUtils.isDigitsOnly(o2)) {
...
} else {
...
}
}
In java if I have initialized a variable in a function that returns an that variable at the end, why can't I return that function?
Here's the some sample code, that I was working
private int spitNumber(int imgNum) {
int returnNum;
switch (imgNum) {
case 1:
case 14:
case 27:
case 40:
returnNum = 1;
break;
case 12:
case 25:
case 38:
case 51:
returnNum = 12;
break;
case 13:
case 26:
case 39:
case 52:
returnNum = 13;
break;
};
return returnNum;
}
When I compile the code I get the error message
error: variable returnNum might not have been initialized
return returnNum;
^
You're using switch but your switch does not cover all the cases.
Think when imgNum = 100, what value will your program assign to returnNum?
Nothing, right?
So you should initialize a starting value for returnNum or provide a default case for switch and assign your returnNum value there
Because you don't have any default case. the message shown says that the variable might not have been initialized, if your value is not among the handled cases.
Need to initialize the variable at the beginning of your code.
Example :
int returnNum = 0;
Primitive types like int, for example, cannot be null. You must initialize it.
I am new in programming. My instructor gave me a special project about number base.
Since the higher number base are a combination of integers and letters, I'm still confused if I should use int and/or char.
import java.util.Scanner;
public class JavaProgram {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter the base you want to convert and base to be converted: ");
int firstBase = in.nextInt();
int secondBase = in.nextInt();
switch(firstBase) {
case 2:
System.out.print("Enter value: ");
// I get confused here already
case 3:
case 4:
case 5:
case 8:
case 10:
case 12:
case 16:
case 20:
case 24:
case 26:
case 27:
case 30:
case 32:
case 36:
}
in.close();
}
}
If you want to store numbers and letters, than you can use char, since technically letters and numbers are characters. Alternatively you can use String, which can store anything from a single character, to complete paragraphs.
Here is a quick overview of some types:
char - only a single letter or character
int - numbers only without decimals
double - numbers with decimals
String - both numbers and letters
So based on your requirement you have to select String.
While I'm executing this code, writing + is converting my integer into a String.
public class Test {
public static void main(String...string){
int m=9;
int k=10;
String s=new String(m +"");//automatic type conversion from int to string
String j=m+"" +k;////automatic type conversion from int to string
System.out.println(s+j);
String s1=String.valueOf(m);
System.out.println(s1);
}
}
I'm unable to understand what + is doing here, and how it's getting converted into a String. Does this have something to do with the right to left precedence of the = operator?
Does this have Got something to do with precedence with right to left of = operator ?
Answer: No
And it's has got nothing to do With Integer Type too.
Why ? because
Here is what JSL say
String conversion applies only to an operand of the binary + operator
which is not a String when the other operand is a String.
In this single special case, the non-String operand to the + is
converted to a String (§5.1.11) and evaluation of the + operator
proceeds as specified in §15.18.1.
So even if you write any other type variable it will convert it Consider this snippet
public static void main(String...string){
double u=9.0;
System.out.println(u+"hi");
}
It gives me output
9.0hi
Now Coming to How ?
For the code snippet that i posted
Here is the part of compiled code of this
public static void main(java.lang.String...);
flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
Code:
stack=5, locals=3, args_size=1
0: ldc2_w #16 // double 9.0d
3: dstore_1
4: getstatic #18 // Field java/lang/System.out:Ljav
a/io/PrintStream;
7: new #24 // class java/lang/StringBuilder
10: dup
11: dload_1
12: invokestatic #26 // Method java/lang/String.valueOf
:(D)Ljava/lang/String;
15: invokespecial #32 // Method java/lang/StringBuilder.
"<init>":(Ljava/lang/String;)V
18: ldc #35 // String hi
20: invokevirtual #37 // Method java/lang/StringBuilder.
append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
23: invokevirtual #41 // Method java/lang/StringBuilder.
toString:()Ljava/lang/String;
26: invokevirtual #45 // Method java/io/PrintStream.prin
tln:(Ljava/lang/String;)V
So internally it invokes valueOf() method to convert double or non-string operand to String and than invokes append() to convert it into String totally .
Hope this helps you :)
I want to make the answer more simpler hence I am posting this.
'+' is the only operator in java that is overloaded for String type for string concatenation.
So if any one of the two operands is String.. the whole operation is overloaded for concatenation.
So string+(any other datatype) = string.
So for any other operands use parentthesis along with string
So 5+5+"" =55
and (5+5)+"" = 10
NOTE: It has nothing to do with right to left precedence
Greetings,
Let's say you wanted to test a string to see if it's an exact match, or, if it's a match with an _ and any number of characters appended following the _
Valid match examples:
MyTestString
MyTestString_
MyTestString_1234
If performance was a huge concern, which methods would you investigate? Currently I am doing the following:
if (String.equals(stringToMatch)) {
// success
} else {
if (stringToMatch.contains(stringToMatch + "_")) {
// success
}
// fail
}
I tried replacing the pattern the String.contains _ with a Java.util.regex.Pattern match on _*, but that performed much worse. Is my solution here ideal or can you think of something more cleaver to improve performance a bit more?
Thanks for any thoughts
You can do something like
if(string.startsWith(testString)) {
int len = testString.length();
if(string.length() == len || string.charAt(len) == '_')
// success
}
I assume you want the testString to appear even if you have a "_"?
EDIT: On whether to use one long condition or nested if statements, there is no difference in code or performance.
public static void nestedIf(boolean a, boolean b) {
if (a) {
if (b) {
System.out.println("a && b");
}
}
}
public static void logicalConditionIf(boolean a, boolean b) {
if (a && b) {
System.out.println("a && b");
}
}
compiles to the same code. If you do javap -c
public static void nestedIf(boolean, boolean);
Code:
0: iload_0
1: ifeq 16
4: iload_1
5: ifeq 16
8: getstatic #7; //Field java/lang/System.out:Ljava/io/PrintStream;
11: ldc #8; //String a && b
13: invokevirtual #9; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
16: return
public static void logicalConditionIf(boolean, boolean);
Code:
0: iload_0
1: ifeq 16
4: iload_1
5: ifeq 16
8: getstatic #7; //Field java/lang/System.out:Ljava/io/PrintStream;
11: ldc #8; //String a && b
13: invokevirtual #9; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
16: return
The complied code is identical.
You could use regular expressions to match patterns. You can use stringToMatch.matches(".*?_.*?"). This returns a boolean.
I ran some benchmarks. This is the quickest I can get.
String a = "Test123";
String b = "Test123_321tseT_Test_rest";
int len1 = a.length();
int len2 = b.length();
if ((len1 == len2 || (len2 > len1 && (b.charAt(len1)) == '_'))
&& b.startsWith(a)) {
System.out.println("success");
} else {
System.out.println("Fail");
}
This will at least work correctly at reasonable performance.
Edit: I switched the _ check and the startsWith check, since startsWith will have worse perforam the _ check.
Edit2: Fixed StringIndexOutOfBoundsException.
Edit3: Peter Lawrey is correct that making only 1 call to a.length() spares time. 2.2% in my case.
Latest benchmark shows I'm 88% faster then OP and 10% faster then Peter Lawrey's code.
Edit4: I replace all str.length() with a local var, and ran dozen more benchmarks. Now the results of the benchmarks are getting so random it's impossible to say what code is faster. My latest version seems to win by a notch.