Firstly, lean about the primitive data types in Java.
If your background is JavaScript, which has no char
type, you might have been thinking that char
is a "kind of" string, but it's not.
char
- is a 16-bit numeric primitive data type, which has a minimum value of '\u0000' (or 0
) and a maximum value of '\uffff' (or 65,535
) which was meant to represent Unicode-characters. But in the earlier days of Java the Unicode standard has been changed, and char
type appeared to be broken, to fix this code points were introduced in the language.
In this statement a = Integer.valueOf(s);
character s
is being promoted into int
type and method valueOf()
creates an unnecessary instance of Integer
which is being immediately thrown away, and you end up with a
having a value in the range from 48
(0
) to 57
(9
), which is greater than array's length. Therefore, you're getting a justifiable ArrayIndexOutOfBoundsException
.
Also, there are few more issues.
Compiler will not complain that you're creating a new array for each method call but this approach is wrong, the string array should be static
, i.e. it should reside on a class level:
public static final String[] DIGITS = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
Another important issue which might seem unimportant is that the names you're using both uninformative (like arr
) and they violate the Java naming convention (like Print_Digits
).
Also, C-style of array declarationString arr[]
is not considered to be a good practice in Java because it mixes the data type and the variable name.
And here is a couple of solutions for this problem.
The first one is somewhat close to code provided by OP:
public static void printDigits1(int num) {
String numericString = String.valueOf(num);
for (int i = 0; i < numericString.length(); i++) {
String digit = DIGITS[Character.getNumericValue(numericString.charAt(i))];
System.out.print(digit + " ");
}
}
We can also address this problem without using strings at all:
public static void printDigits2(int num) {
if (num == 0) {
System.out.println(DIGITS[0]);
return;
}
int len = (int) Math.ceil(Math.log10(num));
String[] result = new String[len];
for (int cur = num, i = len - 1; cur > 0; cur /= 10, i--) {
result[i] = DIGITS[cur % 10];
}
System.out.println(String.join(" ", result));
}
And here's a concise solution using Stream API:
public static void printDigits3(int num) {
String result = String.valueOf(num).chars()
.map(Character::getNumericValue)
.mapToObj(i -> DIGITS[i])
.collect(Collectors.joining(" "));
System.out.println(result);
}
main()
public static void main(String[] args) {
printDigits1(59);
System.out.println();
printDigits2(128);
printDigits3(789);
}
Output:
five nine
one two eight
seven eight nine
A link to Online Demo