Error when try to parse String to Double - java

i have a string like this
106.826820,-6.303850,0
which i get from parsing the google Maps KML Document.
now i wanna parse its string to Double
this is my code :
public Double getLatitude(){
for(int posisi = GPS_NAME.indexOf(","); posisi > GPS_NAME.length(); posisi++){
TEMP_LAT = "" + GPS_NAME.indexOf(posisi);
}
GPS_LATITUDE = Double.valueOf(TEMP_LAT);
return GPS_LATITUDE;
}
public Double getLongitude(){
int posisiakhir = GPS_NAME.indexOf(",");
for(int i = 0; i < posisiakhir; i++){
TEMP_LON = "" + GPS_NAME.indexOf(i);
}
GPS_LONGITUDE = Double.valueOf(TEMP_LON);
return GPS_LONGITUDE;
}
but when i try to run it i got error like this
could somebody help me solving my problems >_<

and also confirm GPS_LATITUDE = Double.valueOf(TEMP_LAT); TEMP_LAT is not null there - as exception is NullPointerException not NumberFormatException.

You have null pointer exception so you should to it like this:
public Double getLatitude(){
for(int posisi = GPS_NAME.indexOf(","); posisi > GPS_NAME.length(); posisi++){
TEMP_LAT = "" + GPS_NAME.indexOf(posisi);
}
if (TEMP_LAT != null) {
GPS_LATITUDE = Double.parseDouble(TEMP_LAT);
}
return GPS_LATITUDE;
}
And for converting to double rather you should use Double.parseDouble() or also you can use new Double(TEMP_LAT).doubleValue() but first approach is cleaner.

Besides the probable causes for the NPE, I don't really get your logic; it looks completely dodgy to me.
Just some examples:
GPS_NAME.indexOf(",") will either return -1 or an index that is smaller than the length of the string in which is being searched. Then why have a condition that checks if it is larger than the length? posisi > GPS_NAME.length() will never be true, hence the for loops are useless...
Then inside the loops you do TEMP_LAT = "" + GPS_NAME.indexOf(posisi). From the earlier remark we know that posisi is either -1 or some other number that is smaller than the length of the string. So GPS_NAME.indexOf(posisi) will try to find a character repesented by the integer posisi (which will be a rather small number) in the string. How does that make sense?
I'd like to advise you to rethink your logic - perhaps String.split(",") is a good starting point.

Use Double.parseDouble(TEMP_LAT);

Related

Result not null in my code, if "sorIndex" is invalid

I would need some guidance from You, at the moment I have this challenge with this exercise:
The aim of this code would be, to split a String(szoveg) to rows and give back the result row(sorIndex) as a result, if sorIndex is in the range of the String Array(String szoveg is splitted into this array).
If the requested number of the row is not in the valid range(0-length of the array) it should give back a null value. The IDE for testing the excercise returns a mistake, which is the following(Hungarian + English):
"A getSor() metódus nem működik jól. Nem létező sorIndexet megadva
null-t kell visszaadjon a metódus. A konstruktor paramétere:"
"The getSor() method is not working properly. Given a not valid
sorIndex, the method should return null. The parameter of the
constructor:" -there is nothing after this part in the IDE.
public String getSor(int sorIndex) {
int sorok= szoveg.split("\n").length;
String sor;
if (sorIndex >= 0 && sorIndex <= sorok) {
String[] stringTomb = new String[sorok];
stringTomb = szoveg.split("\n");
sor = stringTomb[sorIndex];
} else {
sor = null;
}
return sor;
}
Does anyone have any idea where did I made the mistake?
Thank you!
The error message tells you that if an invalid sorIndex is passed, then a null should be returned. This means that instead of getting into the else branch in your logic, it goes into the if in an invalid manner.
The reason of this is that arrays are 0-indexed, so you should compare against rows (sorok) in a srict manner:
if (sorIndex >= 0 && sorIndex < sorok) {
That should fix the issue. However, your code computes split several times and is superfluous. I would refactor it to:
public String getSor(int sorIndex) {
if (szoveg == null) return null; // Handling the case when szöveg is not properly initialized
String stringTomb[] = szoveg.split("\n");
return ((sorIndex >= 0) && (sorIndex < szoveg.length)) ? stringTomb[sorIndex] : null;
}
I used the ternary operator to make this more readable, concise and short.

java.lang.StringIndexOutOfBoundsException Error while reading Binary String

I have a long String with binary values. And i have a hash map that has the Binary digits as a key and char as a value. I have a function that supposed to read the binary string using 2 pointers and compare with hashmap and store the corresponding char in main.decodedTxt. However, im getting string out of bound exception for this. I don't know how to solve this. I'm getting exception on "String temp =" line. I have a picture link of the console output to see better picture.
public static void bitStringToText (String binText){
String bs = binText;
int from =0;
int to = 1;
while(bs != null){
String temp = bs.substring(from, to);
if (main.newMapDecoding.containsKey(temp)){
main.decodedTxt += main.newMapDecoding.get(temp);
from =to;
to = from +1;
} else {
to = to + 1;
}
}
}
Image of console exception is here
First of all there is no need to check if bs is null because no part of your code changes the value of bs. Your current code will cross the possible index of your binText at some point. It's better to loop just binText and check if you find something within it. After all you have to traverse the complete string anyways. Change your code as follows
public static void bitStringToText (String binText){
//no need to do this if you are not modifying the contents of binText
//String bs = binText;
int from =0;
int to = 1;
int size = binText.length();
String temp = "";
while(to <= size ){
temp = binText.substring(from, to);
if (main.newMapDecoding.containsKey(temp)){
main.decodedTxt += main.newMapDecoding.get(temp);
from =to;
to = from +1;
} else {
to = to + 1;
}
}
}
Hope it helps.
First, give it a try to practice debugging. It is an easy case. Either use run in debug mode (place break point on String temp = bs.substring(from, to); line) or print values of from and to before the same line. It will help to understand what is going on.
Solution:
If bs is not null you will always have StringIndexOutOfBoundsException. Because you are not checking if to is pointing to not existed index of bs String. Easiest example of the first one will be empty String: bs == "".
One of the solution could be to replace condition in while to while (to <= bs.length()).

What am I missing with this code? Google foo.bar

So recently I got invited to this google foo.bar challenge and I believe the code runs the way it should be. To be precise what I need to find is the number of occurrences of "abc" in a String. When I verify my code with them, I pass 3/10 test cases. I'm starting to feel bad because I don't know what I am doing wrong. I have written the code which I will share with you guys. Also the string needs to be less than 200 characters. When I run this from their website, I pass 3 tests and fail 7. Basically 7 things need to be right.
The actual question:
Write a function called answer(s) that, given a non-empty string less
than 200 characters in length describing the sequence of M&Ms. returns the maximum number of equal parts that can be cut from the cake without leaving any leftovers.
Example : Input : (string) s = "abccbaabccba"
output : (int) 2
Input: (string) s = "abcabcabcabc"
output : (int) 4
public static int answer(String s) {
int counter = 0;
int index;
String findWord ="ABC";
if(s!=null && s.length()<200){
s = s.toUpperCase();
while (s.contains(findWord))
{
index = s.indexOf(findWord);
s = s.substring(index + findWord.length(), s.length());
counter++;
}
}
return counter;
}
I see a couple of things in your code snippet:
1.
if(s.length()<200){
Why are you checking for the length to be lesser than 200? Is that a requirement? If not, you can skip checking the length.
2.
String findWord ="abc";
...
s.contains(findWord)
Can the test program be checking for upper case alphabets? Example: "ABC"? If so, you might need to consider changing your logic for the s.contains() line.
Update:
You should also consider putting a null check for the input string. This will ensure that the test cases will not fail for null inputs.
The logic of your code is well but on the other hand i found that you didn't check for if input string is empty or null.
I belief that google foo.bar wants to see the logic and the way of coding in a proper manner.
so don't be feel bad
I would go for a simpler approach
int beforeLen = s.length ();
String after = s.replace (findWord, "");
int afterLen = after.length ();
return (beforeLen - afterLen) / findWord.length ();
String pattern = "abc";
String line="<input text here>";
int i=0;
Pattern TokenPattern=Pattern.compile(pattern);
if(line!=null){
Matcher m=TokenPattern.matcher(line);
while(m.find()){
i++;
}}
System.out.println("No of occurences : "+ " "+i);
put declaration of index out before while block, isn't never good re-declare the same variable n time.
int index;
while (s.contains(findWord))
{
index = s.indexOf(findWord);
....
}
I hope this help
Update:
try to compact your code
public static int answer(String s) {
int counter = 0;
int index;
String findWord = "ABC";
if (s != null && s.length() < 200) {
s = s.toUpperCase();
while ((index = s.indexOf(findWord)) > -1) {
s = s.substring(index + findWord.length(), s.length());
counter++;
}
}
return counter;
}
Update:
The logic seems good to me, I'm still try to improve the performance, if you can try this
while ((index = s.indexOf(findWord, index)) > -1) {
//s = s.substring(index + findWord.length(), s.length());
index+=findWord.length();
counter++;
}

Why double is converted to int in JSON string

I just coded to put an array of double values in the JsonObject. But, all my double values are converted to int values, when i print it. can someone help me understand what is happening behind? Please let me know the best way to put primitive arrays in JsonObject
public class JsonPrimitiveArrays {
public static void main(String[] args) {
JSONObject jsonObject = new JSONObject();
double[] d = new double[]{1.0,2.0,3.0};
jsonObject.put("doubles",d);
System.out.println(jsonObject);
}
}
Output:
{"doubles":[1,2,3]}
Its in real not getting converted into int. Only thing happening is as JS Object its not showing .0 which is not relevant.
In your sample program, change some of the value from double[] d = new double[]{1.0,2.0,3.0} to
double[] d = new double[]{1.0,2.1,3.1} and run the program.
You will observer its in real not converting into int. The output you will get is {"doubles":[1,2.1,3.1]}
Looking at toString of net.sf.json.JSONObject it eventually calls the following method to translate the numbers to String (source code here):
public static String numberToString(Number n) {
if (n == null) {
throw new JSONException("Null pointer");
}
//testValidity(n);
// Shave off trailing zeros and decimal point, if possible.
String s = n.toString();
if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) {
while (s.endsWith("0")) {
s = s.substring(0, s.length() - 1);
}
if (s.endsWith(".")) {
s = s.substring(0, s.length() - 1);
}
}
return s;
}
It clearly tries to get rid of the trailing zeroes when it can, (s = s.substring(0, s.length() - 1) if a String is ending in zero).
System.out.println(numberToString(1.1) + " vs " + numberToString(1.0));
Gives,
1.1 vs 1
All numbers are floats in Javascript. So, 1.0 and 1 are the same in JS. There is no differenciation of int, float and double.
Since JSON is going to end up as a JS object, there is no use in adding an extra '.0' since '1' represents a float as well. I guess this is done to save a few bytes in the string that is passed around.
So, you will get a float in JS, and if you parse it back to Java, you should get a double. Try it.
In the mean time, if you are interested in the way it displays on screen, you can try some string formatting to make it look like '1.0'.

Remove trailing zero in Java

I have Strings (from DB), which may contain numeric values. If it contains numeric values, I'd like to remove trailing zeros such as:
10.0000
10.234000
str.replaceAll("\\.0*$", ""), works on the first one, but not the second one.
A lot of the answers point to use BigDecimal, but the String I get may not be numeric. So I think a better solution probably is through the Regex.
there are possibilities:
1000 -> 1000
10.000 -> 10 (without point in result)
10.0100 -> 10.01
10.1234 -> 10.1234
I am lazy and stupid, just
s = s.indexOf(".") < 0 ? s : s.replaceAll("0*$", "").replaceAll("\\.$", "");
Same solution using contains instead of indexOf as mentioned in some of the comments for easy understanding
s = s.contains(".") ? s.replaceAll("0*$","").replaceAll("\\.$","") : s
Use DecimalFormat, its cleanest way
String s = "10.1200";
DecimalFormat decimalFormat = new DecimalFormat("0.#####");
String result = decimalFormat.format(Double.valueOf(s));
System.out.println(result);
Kent's string manipulation answer magically works and also caters for precision loss, But here's a cleaner solution using BigDecimal
String value = "10.234000";
BigDecimal stripedVal = new BigDecimal(value).stripTrailingZeros();
You can then convert to other types
String stringValue = stripedVal.toPlainString();
double doubleValue = stripedVal.doubleValue();
long longValue = stripedVal.longValue();
If precision loss is an ultimate concern for you, then obtain the exact primitive value. This would throw ArithmeticException if there'll be any precision loss for the primitive. See below
int intValue = stripedVal.intValueExact();
String value = "10.010"
String s = new DecimalFormat("0.####").format(Double.parseDouble(value));
System.out.println(s);
Output:
10.01
I find all the other solution too complicated. Simply
s.replaceFirst("\\.0*$|(\\.\\d*?)0+$", "$1");
does the job. It tries the first alternative first, so that dot followed by all zeros gets replaced by nothing (as the group doesn't get set). Otherwise, if it finds a dot followed by some digits (as few as possible due to the lazy quantifier *?) followed by some zeros, the zeros get discarded as they're not included in the group. It works.
Warning
My code relies on my assumption that appending a unmatched group does nothing. This is true for the Oracle implementation, but not for others, including Android, which seem to append the string "null". I'd call the such implementations broken as it just may no sense, but they're correct according to the Javadoc.
The following works for all the following examples:
"1" -> "1"
"1.0" -> "1"
"1.01500" -> "1.015"
"1.103" -> "1.103"
s = s.replaceAll("()\\.0+$|(\\..+?)0+$", "$2");
What about replacing
(\d*\.\d*)0*$
by
\1
?
You could replace with:
String result = (str.indexOf(".")>=0?str.replaceAll("\\.?0+$",""):str);
To keep the Regex as simple as possible. (And account for inputs like 1000 as pointed out in comments)
My implementation with possibility to select numbers of digits after divider:
public static String removeTrailingZero(String number, int minPrecise, char divider) {
int dividerIndex = number.indexOf(divider);
if (dividerIndex == -1) {
return number;
}
int removeCount = 0;
for (int i = dividerIndex + 1; i < number.length(); i++) {
if (number.charAt(i) == '0') {
removeCount++;
} else {
removeCount = 0;
}
}
int fracLen = number.length() - dividerIndex - 1;
if (fracLen - removeCount < minPrecise) {
removeCount = fracLen - minPrecise;
}
if (removeCount < 0) {
return number;
}
String result = number.substring(0, number.length() - removeCount);
if (result.endsWith(String.valueOf(divider))) {
return result.substring(0, result.length() - 1);
}
return result;
}
In addition to Kent's answer.
Be careful with regex in Kotlin. You have to manually write Regex() constructor instead of a simple string!
s = if (s.contains("."))
s.replace(Regex("0*\$"),"").replace(Regex("\\.\$"),"")
else s
Try to use this code:
DecimalFormat df = new DecimalFormat("#0.#####");
String value1 = df.format(101.00000);
String value2 = df.format(102.02000);
String value3 = df.format(103.20000);
String value4 = df.format(104.30020);
Output:
101
102.02
103.2
104.3002
Separate out the fraction part first. Then you can use the below logic.
BigDecimal value = BigDecimal.valueOf(345000);
BigDecimal div = new BigDecimal(10).pow(Integer.numberOfTrailingZeros(value.intValue()));
System.out.println(value.divide(div).intValue());

Categories