I would like to key in my nirc number e.g. S1234567I and then put 1234567 individualy as a integer as indiv1 as charAt(1), indiv2 as charAt(2), indiv as charAt(3), etc. However, when I use the code below, I can't seem to get even the first number out? Any idea?
Scanner console = new Scanner(System.in);
System.out.println("Enter your NRIC number: ");
String nric = console.nextLine();
int indiv1 = nric.charAt(1);
System.out.println(indiv1);
You'll be getting 49, 50, 51 etc out - those are the Unicode code points for the characters '1', '2', '3' etc.
If you know that they'll be Western digits, you can just subtract '0':
int indiv1 = nric.charAt(1) - '0';
However, you should only do this after you've already validated elsewhere that the string is of the correct format - otherwise you'll end up with spurious data - for example, 'A' would end up returning 17 instead of causing an error.
Of course, one option is to take the values and then check that the results are in the range 0-9. An alternative is to use:
int indiv1 = Character.digit(nric.charAt(1), 10);
This will return -1 if the character isn't an appropriate digit.
I'm not sure if this latter approach will cover non-Western digits - the first certainly won't - but it sounds like that won't be a problem in your case.
Take a look at Character.getNumericValue(ch).
try {
int indiv1 = Integer.parseInt ("" + nric.charAt(1));
System.out.println(indiv1);
} catch (NumberFormatException npe) {
handleException (npe);
}
tl;dr
The modern solution uses Unicode code point numbers rather than the outmoded char type.
Here is an IntStream, a successive stream of each character’s code point number, printing each of those numbers to console:
"S1234567I"
.codePoints()
.forEach( System.out :: println )
83
49
50
51
52
53
54
55
73
Show each character along with its code point number. To convert a code point number back into a character, call Character.toString while passing the integer: Character.toString( codePoint ).
String s = Character.toString( 49 ) ; // Returns "1".
…and…
String s = Character.toString( 128_567 ) ; // Returns "😷" FACE WITH MEDICAL MASK.
Example:
"S1234567I".codePoints().forEach( ( int codePoint ) -> {
String message = Character.toString( codePoint ) + " → " + codePoint;
System.out.println( message );
} );
S → 83
1 → 49
2 → 50
3 → 51
4 → 52
5 → 53
6 → 54
7 → 55
I → 73
Unicode code point
The char type is obsolete, unable to represent even half of the 143,859 characters defined in Unicode. The char type is a 16-bit number underneath, capable of representing a range of numbers of about ± 64,000. Unicode characters are assigned numbers along a range of about a million, too big for char to handle.
Instead, use Unicode code point integer numbers to represent individual characters.
We can get a stream of int primitive values (IntStream) from a string, each number representing the Unicode code point of each successive character.
IntStream intStream = "S1234567I".codePoints() ;
Process each code point number. Here we simply print each number.
intStream.forEach( System.out :: println );
When run.
83
49
50
51
52
53
54
55
73
Or perhaps you want an array of the int numbers.
int[] codePoints = "S1234567I".codePoints().toArray();
Dump to console.
System.out.println( "codePoints = " + Arrays.toString( codePoints ) );
codePoints = [83, 49, 50, 51, 52, 53, 54, 55, 73]
Or perhaps you want a List object containing all those code point numbers. Here is a non modifiable list made by List.of. We call boxed to invoke auto-boxing feature to convert int primitives into Integer objects. Then a Collector implementation gathers the output of the stream into a List.
List < Integer > codePoints = "S1234567I".codePoints().boxed().collect( Collectors.toList() );
Explaining those parts:
List < Integer > codePoints = // Desired result is a `List` collection of `Integer` objects.
"S1234567I" // Your input string.
.codePoints() // Generate an `IntStream`, a succession of `int` integer numbers representing the Unicode code point number of each character in the `String` object.
.boxed() // Convert each `int` primitive to an `Integer` object.
.collect( // Collect the produced `Integer` objects together.
Collectors.toList() // Specify a `Collector` implementation that knows how to make a `List` object, containing our `Integer` objects.
) // Returns a `List` of `Integer` objects.
;
Pull digits
Perhaps you want to filter out the alphabetic characters to leave only the digits found in your input string. The Character class offers tests such as isDigit.
For an input of "S1234567I", that means dropping the S and the I, leaving 1234567, producing the integer number 1,234,567.
List < Integer > codePointsOfDigitsFromInput = "S1234567I".codePoints().filter( ( int codePoint ) -> Character.isDigit( codePoint ) ).boxed().collect( Collectors.toList() );
Break that out to multiple lines.
List < Integer > codePointsOfDigitsFromInput =
"S1234567I"
.codePoints()
.filter(
( int codePoint ) -> Character.isDigit( codePoint )
)
.boxed()
.collect( Collectors.toList() );
codePointsOfDigitsFromInput = [49, 50, 51, 52, 53, 54, 55]
We can modify that code to generate a String containing only digits taken from that input. See Question, Make a string from an IntStream of code point numbers?. And then we make an int integer number of that text.
String numberComponentFromInput =
"S1234567I"
.codePoints()
.filter(
( int codePoint ) -> Character.isDigit( codePoint )
)
.collect( // Collect the results of processing each code point.
StringBuilder :: new , // Supplier<R> supplier
StringBuilder :: appendCodePoint , // ObjIntConsumer<R> accumulator
StringBuilder :: append // BiConsumer<R,R> combiner
)
.toString();
int x = Integer.valueOf( numberComponentFromInput );
numberComponentFromInput = 1234567
x = 1234567
I know question is about char to int but this worth mentioning because there is negative in char too ))
From JavaHungry you must note the negative numbers for integer
if you dont wana use Character.
Converting String to Integer : Pseudo Code
1. Start number at 0
2. If the first character is '-'
Set the negative flag
Start scanning with the next character
For each character in the string
Multiply number by 10
Add( digit number - '0' ) to number
If negative flag set
Negate number
Return number
public class StringtoInt {
public static void main (String args[])
{
String convertingString="123456";
System.out.println("String Before Conversion : "+ convertingString);
int output= stringToint( convertingString );
System.out.println("");
System.out.println("");
System.out.println("int value as output "+ output);
System.out.println("");
}
public static int stringToint( String str ){
int i = 0, number = 0;
boolean isNegative = false;
int len = str.length();
if( str.charAt(0) == '-' ){
isNegative = true;
i = 1;
}
while( i < len ){
number *= 10;
number += ( str.charAt(i++) - '0' );
}
if( isNegative )
number = -number;
return number;
}
}
int indiv1 = Integer.parseInt(nric.charAt(1));
Related
The following code prints A to the console:
char ch = (char)65.25;
System.out.println(ch);
However I don't understand why the next piece of code doesn't print the ASCII character?
int rand = (int)currentSeconds % 26;
System.out.println(" the number is " + rand);
char randN = (char)rand;
System.out.println(randN);
Below follows the full code:
System.out.println(System.currentTimeMillis());
System.out.println(" using current second to generate random Uppercase letter");
long totalsecs = System.currentTimeMillis()/1000;
long currentSeconds = totalsecs % 60;
long totalMinute = totalsecs/60;
long currentMinute = totalMinute%60;
long totalHours = totalMinute/60;
long currentHours = totalHours%24;
System.out.println("current time is " +currentHours +":"+ currentMinute +":"+currentSeconds);
int rand = (int)currentSeconds % 26;
System.out.println(" the number is " + rand);
char randN = (char)rand;
System.out.println(randN);
There are many versions of the println method, with different parameter types. In other words, if s is a String, i is an int and c is a char, then System.out.println(i) is actually calling a different method from System.out.println(c), which is calling a different method from System.out.println(s). It's the compiler's job to figure out which method you're trying to call, and it takes into account the type of the expression that you pass in. So
System.out.println(rand) calls the int version of the method, which prints the number.
System.out.println(randN) calls the char version of the method, which prints the character, rather than its numeric equivalent.
System.out.println("the number is " + rand) calls the String version of the method, which prints a String, and in this case, the String is made by concatenating the number to the end of a String literal.
If you're trying to print a character value in the range A to Z in place of a number from 0 to 25, then writing char randN = (char) rand; isn't enough - that won't actually convert the number to the range you want, because the numeric values of the characters from A to Z are not actually 0 to 25.
You need to write char randN = 'A' + rand; to effect the desired conversion.
tl;dr
Character.toString
(
"A".codePointAt( 0 )
+
ThreadLocalRandom.current().nextInt( 0 , 27 )
)
Or:
Character.toString
(
ThreadLocalRandom.current().nextInt( 65 , ( 65 + 27 ) )
)
Start with A
As others pointed out, to get a random character from A-Z, you need to add 0-25 to a starting number, that number being the code for A which is 65.
Avoid char
Another problem with your code is its use of the char. The char type in Java is legacy, essentially broken. As a 16-bit value, that type cannot represent most characters.
While your particular case of A-Z works with char, using char is a bad habit, and an unnecessary habit.
Code points
Instead learn to use Unicode code point integer numbers. Unicode is a superset of US-ASCII, so code points 0-127 represent the same characters in both.
int codePointForA = "A".codePointAt( 0 ) ; // 65
int addend = ThreadLocalRandom.current().nextInt( 0 , 27 ) ; // ( inclusive , exclusive )
int randomCodePoint = ( codePointForA + addend ) ;
String randomCharacter = Character.toString( randomCodePoint ) ;
See code run live at IdeOne.com.
Z
I am new to java and and working on a crud calculator that takes input and holds it in an ArrayList to perform the calculations.
I am trying to add two values in an ArrayList<Character> and then replace the "+" with the sum.
if(listEqu.contains('+')) {
while(listEqu.indexOf('+') > -1) {
int plus = listEqu.indexOf('+');
int prev = listEqu.get(plus-1);
int nxt = listEqu.get(plus+1);
Character sum = (char) (nxt + prev);
listEqu.set(plus, sum);
System.out.println(listEqu);
}
}
When the input is 1+1, this returns [1, b, 1].
What I want is to return [1, 2, 1] .
Any advice? Thanks!
The problem is actually that adding two characters doesn't do what you expect.
The value of '1' + '1' is 'b'. If you want the next digit after '1' you add the integer 1 to it; i.e. '1' + 1 is '2'.
For a deeper understanding, you need to understand how character data is represented in Java.
Each char value in Java is an unsigned 16 bit integer that corresponds to a code point (or character code) in the Unicode basic plane. The first 128 of these code points (0 to 127) correspond to a characters in the old ASCII character set. In ASCII the codes that represent digits are 48 (for '0') through to 39 (for '9'). And the lowercase letters are 97 (for 'a') through to 122 (for 'z').
So as you can see, '1' + '1' -> 49 + 49 -> 98 -> 'b'.
(In fact there is a lot more to it than this. Not all char values represent real characters, and some Unicode code-points require two char values. But this is way beyond the scope of your question.)
How could I specify addition of numbers instead of addition of the characters?
You convert the character (digit) to a number, perform the arithmetic, and convert the result back to a character.
Read the javadoc for the Character class; e.g. the methods Character.digit and Character.forDigit.
Note that this only works while the numbers remain in the range 0 through 9. For a number outside of that range, the character representation consists of two or more characters. For those you should be using String rather than char. (A String also copes with the 1 digit case too ...)
Few things that can be improved with your code :
Converting the characters 1 into equivalent integer value:
int prev = Integer.parseInt(String.valueOf(listEqu.get(plus-1)));
int nxt = Integer.parseInt(String.valueOf(listEqu.get(plus+1)));
// Note : int prev = listEqu.get(plus-1) would store an ascii value of `1` to prev value i.e 49
And then converting the sum of those two values into Character back to be added to the list using Character.forDigit as:
Character sum = Character.forDigit(nxt+prev,10);
// Note Character sum = (char) (nxt + prev); is inconvertible
// and char sum = (char) (nxt + prev); would store character with ascii value 98(49+49) in your case 'b' to sum
you should first convert your prevand nxt to int value and then add them together like follow:
if(listEqu.contains('+')) {
while(listEqu.indexOf('+') > -1) {
int plus = listEqu.indexOf('+');
int prev = Integer.parseInt(listEqu.get(plus-1));
int nxt = Integer.parseInt(listEqu.get(plus+1));
Character sum = (char) (nxt + prev);
listEqu.set(plus, sum);
System.out.println(listEqu);
}
}
nxt and prev are char values. Tey take their value in the ASCII table, where '1' is 61 and 'b' is 142 (thus, '1' + '1' = 'b')
You need to substract '0' to get the number they represent. ('1' - '0' = 61 - 60 = 1)
The sum is not necessarily writable with one character, so you shouldn't put it back into a char array.
If you want to convert an integer to a string, use Integer.toString(i).
(And, if you want to, get the first character of the string and put it in the array, if that's what you want)
You need to parse the characters to their corresponding decimal value before you perform the addition, and then back to a character after. The methods Character.digit(char, int) and Character.forDigit(int, int) can do that (and I would use char since that is the type of prev and nxt). Like,
char prev = listEqu.get(plus - 1);
char nxt = listEqu.get(plus + 1);
Character sum = Character.forDigit(Character.digit(nxt, 10)
+ Character.digit(prev, 10), 10);
We have a very weird requirement to convert 11 digit hexadecimal number ( range from (A0000000001 ~ AFFFFFFFFFF) ) to 11 digit decimal number. And there should be 1:1 mapping between hexadecimal to integer. Is there a way to do this in Java ?
This is not possible, in Java or in any other language or system. This impossibility is a fundamental property of numbers and set theory.
Since the leading 0xA does not change, what you actually have is a 10-hex digit value, or 40 bits worth of data.
This encompasses about 1.1 x 1012 possible values, so it is not possible to map this to an 11-digit decimal number, which by definition has only 1011 possible values.
Based on the comments I'm going to make this more explicit. Start with 0xA0000000000 and map that to decimal 00000000000, then increment both by 1 to establish a one-to-one correspondence between members of the two sets and repeat:
0xA0000000000 -> 00000000000
0xA0000000001 -> 00000000001
0xA0000000002 -> 00000000002
...
0xA0000000010 -> 00000000016
...
0xA0000000100 -> 00000000256
...
0xA0000001000 -> 00000004096
...
0xA174876E7FF -> 99999999999
...
0xA174876E800 -> oops! overflow! too many digits
Put another way, the size of the set of all hex values between 0xA0000000000 and 0xAFFFFFFFFFF is larger than the set of all decimal values between 00000000000 and 99999999999.
String hexNumber = ...
int decimal = Integer.parseInt(hexNumber, 16);
Not sure if you need to display ten characters or not. If so, here is some code to convert it into a string and pad leading zeros.
String decNumber = Integer.toString(decimal);
public static String padLeadingZeros(String data, int requiredLength){
StringBuffer sb = new StringBuffer();
int numLeadingZeros = requiredLength - data.length();
for (int i=0; i < numLeadingZeros; i++){
sb.append("0");
}
sb.append(data);
return sb.toString();
}
I am trying a code problem to convert double to string and then insert that to an array. I tried various methods but these don't give expected output.
public int[] makePi() {
double PI = Math.PI;
String sPI = String.valueOf(PI);
int[] Arr = new int[3];
for(int i =0; i<3; i++)
{
Arr[i] = sPI.charAt(i);
}
return Arr;
}
Output should be an array with first three characters of PI as below :-
[ 3, 1, 4 ] while I am getting [51, 46, 49]
I will handle decimal character if needed.
Just a hint is needed.
Please don't provide full program that will be a spoiler. :-)
Look at the ASCII table. Do you see what are the corresponding chars for the integers you're getting? This should be a good hint for you.
Note that you're assigning the result to an int array, while you're running on characters.
you're storing chars into an int array. hence theie respective ascii values will be stored in array (you're effectively converting char to int)
3 (char) -> 51 (ASCII Value)
. (char) -> 46 (ASCII Value)
1 (char) -> 49 (ASCII Value)
your array length is 3, so only first 3 chars are converted to ascii which is 3.1, not 3.14
But now if you want to store it into an char array (which i feel you're trying to do), all you need is -
char[] charArray = sPI.toCharArray();
Plus, I dont think you want to store in int array as though you can convert ascii values int their respective int value, but what about '.' which is not a valid int.
What you get in your array are values of characters (so something like 70 for '3', I neither remember nor want to remember exact values). You must convert value of character into the number itself. Hint: characters are numbered in the following way:
'0' - n
'1' - n + 1
'2' - n + 2
and so on.
If you want to extract the numeric values of the digits, I would advise against doing explicit comparisons and arithmetic on the character values.
The Character class provides helper methods, which are less error-prone and more readable:
int outIndex = 0;
for (int i = 0; i < 3 /* && i < sPI.length() */; ++i) {
char c = sPI.charAt(i);
if (Character.isDigit(c)) {
Arr[outIndex++] = Character.getNumericValue(c);
}
}
/* assert outIndex == 3 */
return Arr;
I've commented out some code which I'd put in there for more robustness - it's not strictly necessary in this case, since we know that sPI has at least 3 digits in it. (Mind you, if we're going to hard-code that assumption, we may as well simply return new int[] { 3, 1, 4 };).
I need to convert five digit integer to alphanumeric string of length 5.Doing below but sometimes it doesn't provide alphanumeric but numeric value.
Long x = 12345L;
String code = Long.toHexString(x).toUpperCase();
I want to get Alphanumeric string of length 5 always.
Try this
static String alphaNumric(int value) {
String s = "abcde" + Integer.toString(value, 36);
return s.substring(s.length() - 5);
}
and
int[] tests = { 12345, 1, 36, 36 * 36, 32767, 99999 };
for (int i : tests)
System.out.println(i + " -> " + alphaNumric(i));
output
12345 -> de9ix
1 -> bcde1
36 -> cde10
1296 -> de100
32767 -> depa7
99999 -> e255r
That's hardly surprising.
For example, 0x12345 is 74565, so 74565 does not contain any of the digits A to F when converted to hexadecimal.
Given that 99999 is 0x1869F, you have plenty of room in your converted string to accommodate some "junk" data, consider introducing an additive constant (0xA0000 perhaps which at least guarantees at least one alpha character for positive inputs), or even a number that your XOR with your original.