public static double convertWeight(String value, String value2) {
double lbs = 0;
double ounces = 0;
if (!value.equals("")) {
lbs = Double.parseDouble(value);
}
if (!value2.equals("")) {
ounces = Double.parseDouble(value2) * 0.062500;
}
double grams = (lbs + ounces) / 0.0022046;
return grams;
}
I have this piece of code, where at sometimes i get pounds or oz value empty. The above piece of code works fine, but i am not happy the way i have written the code. Can anyone tell me a better alternate way.
I have to convertWeight. So from my service i get sometimes values or sometimes just empty strings. If its empty i ensure that i pass lbs or ounces "Zero" converWeight(value1, value2);
Java 6 implemented a new String method, isEmpty(). As long as you're running 6 or above, you can rewrite your code using this method. It's a bit more readable.
try {
if (!isEmpty(value)) {
lbs = Double.parseDouble(value);
}
if (!isEmpty(value2)) {
ounces = Double.parseDouble(value2) * 0.062500;
}
} catch (NumberFormatException nfe) {
//Do some notification
System.err.println("Invalid input.");
}
As an added suggestion .. You may want to wrap this code in a try/catch block. If you don't, your program will crash with an uncaught exception if it tries to parse anything other than a valid double for either values.
I usually do it this way
if (value != null && !value.trim().isEmpty())
Null check to avoid an NPE
Followed by a trim() to strip any extraneous spaces
Followed by isEmpty() that returns true for length > 0
I recommend using the Apache StringUtils.isEmpty(), .isNotEmpty(), .isBlank() and .isNotBlank(). Keeping Apache Commons around is useful for a lot of Java quirks, not just Strings.
http://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/StringUtils.html
use String.isEmpty method
public static double convertWeight(String value, String value2) {
double lbs = (value.isEmpty())?0:Double.parseDouble(value);
double ounces = (value2.isEmpty())?0:Double.parseDouble(value2) * 0.062500;
return (lbs + ounces) / 0.0022046;
}
Related
How can I write a piece of Java code that checks if a string is convertible to an integer, that is if any character of it is convertible to an integer between 0 and 9 ? I thought of something like this:
String s = "...";
for (int i = 0; i < s.length(); i++)
{
int h = Integer.parseInt(s.substring(i, i + 1));
if (h < 0 || h > 9)
throw new IntegerFormatException();
}
catch (IntegerFormatException e)
{
System.out.println("This is not an integer");
}
where IntegerFormat Exception is something like
public class IntegerFormatException extends Exception
{
public IntegerFormatException()
{
super ("This string isn't convertible to an integer");
}
public IntegerFormatException(String message)
{
super (message);
}
}
But if I then try the code with, say, "8&35" as the string I don't get my message "This is not an integer", but I get and IDE automatic red ink message stating
Exception in thread "main" java.lang.NumberFormatException: For input string: "&"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:569)
at java.lang.Integer.parseInt(Integer.java:615)
at project.pkg9.pkg2.Project92.main(Project92.java:60)
Java Result: 1
Is my code wrong ? If yes, how can I fix it ? Many thanks in advance for all your answers.
There is already a run time exception for that, use it!
String s = "8&35";
try {
int result = Integer.parseInt(s);
System.out.println("This is parsable: " + result);
} catch (NumberFormatException e) {
System.err.println("s is NOT parsable....");
}
That's because Integer.parseInt will throw a NumberFormatException exception if you try to parse something that's not an int, and you don't catch that in your try/catch block. You could catch that in your catch block or use a regex to check what the character is at that location before you try to parse (or, as pointed out in the comments, Character.isDigit()).
Also, there's no need to see if a single digit is less than 0 or greater than 9 - how could a single digit possibly be anything but an integer in the range of 0 - 9? This won't really tell you if the character is a valid int or not because, unless you're comparing the ASCII values, it doesn't make sense to talk about whether & is greater than 9, for example.
I would do it with a Regex :
if(s.matches("[0-9]"))
{
//it's an Integer,
//execute logic
}
Instead of looping you can use regex. This will work and would throw the IntegerFormatException for an empty string as well.
String s = "...";
if (!s.matches("[0-9]+")) {
throw new IntegerFormatException();
}
It won't cover Integer type capacity overflow - I mean a huge number above Integer.MAX_VALUE. Not sure do you need that though.
Integer.parseInt(s.substring(i, i + 1)); throw an exception by itself.
In particular, it throws the java.lang.NumberFormatException: which is not caught by your catch.
If you really need to use your exception (there is already one so why not to use that one?) use the following instead:
public static void main(String[] args) {
String s = "1234/&&56";
try{
for (int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
int h = c-'0';
if (h < 0 || h > 9)
throw new IntegerFormatException();
}
}catch(IntegerFormatException e)
{
System.out.println("This is not an integer");
}
}
Note that you should also include the check for the very first character (it could be the - sign) in the case you are trying to parse signed numbers.
try this
String regex = "^-?[0-9]+$";
if (s.matches(regex) {
// it's a number
} else {
// not a number
}
You should refer to the documentation for the Integer.parseInt(String s) method. The full header for this method is public static int valueOf(String s) throws NumberFormatException and the documentation states that the NumberFormatException is thrown when the string does not contain a parsable integer.
To obtain the functionality you described, you should consider that passing a single char into the function will always result in an integer from 0 to 9 (inclusive) if the char is parsable to an int, so, your if statement is probably unecessary. To make your implementation work, you should catch the NumberFormatException and use that to determine if the char parsed correctly.
Also, to simplify your code, you can also use the s.charAt(i) method rather than s.substring(i, i + 1). You might also want to look into regex to obtain the behavior you explained.
You can use Character class isdigit api or other api to test if it is digit or not
String s = "1234/&&56";
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
if((Character.isDigit(ch))){
System.out.println(ch);
}
}
The function chr($i) returns a one-character string that contains the character equivalent of $i, where $i is an integer between 0 and 255.
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'.
I've got a home automation system working in Java, and I want to add simple math capabilities such as addition, subtraction, multiplication, division, roots, and powers.
At the system current state, it can convert a phrase into tags, as shown in the following examples:
example:
Phrase: "what is one hundred twenty two to the power of seven"
Tagged: {QUESTION/math} {NUMBER/122} {MATH/pwr} {NUMBER/7}
example:
Phrase: "twenty seven plus pi 3 squared"
Tagged: {NUMBER/27} {MATH/add} {NUMBER/3.14159} {MATH/multiply} {MATH/pwr} {NUMBER/2}
This example could be just as easily converted to something like this:
27 + 3.14159 * 3^2
Each tag is an object that can be queried for it value.
Edit: Specific question:
So now I need a way to read that group of tags as an equation, and return a numerical result. As a last resort I could use google or wolfram alpha, but that will be slower, and I'm trying to keep the automation system completely self contained.
If you would like to see the entire source, here it is in github.
Note that I have not committed the last few few changes, so some of the math related things I gave examples will not work.
After some more googleing (I didn't know the name for what I was doing at first) I found someone who has done something similar already:
http://www.objecthunter.net/exp4j/
Edit: Finished:
https://github.com/Sprakle/HomeAutomation/blob/master/src/net/sprakle/homeAutomation/interpretation/module/modules/math/Math.java
What you need is a parsing method that will build an equation and return an answer from your text. I'll take a single line and walk through making such a method which you will then need to work out for yourself. Note that this is just a general idea and that some languages other than Java may be more suitable for this kind of operation.
{QUESTION/math} {NUMBER/122} {MATH/pwr} {NUMBER/7}
//let's assume that the preprocessor reduces the input to an array that is something like this:
// [122, pwr, 7] (this is a very common construction in a language like LISP).
public static int math(string[] question){
while(i < question.length){
if(question[i] == "pwr"){
return pow(Integer.parseInt(question[i-1]), Integer.parseInt(question[i+1]);
}
i++;
}
return 0;
}
Basically what you'll need is a nice way of going from infix to prefix notation with a little bit of string to whatever conversions.
There are likely nicer structures for doing this than what I've produced above, but something like this should get you going.
Ben, he's right. The parsing action that takes natural language is much more difficult. What you need to do is add math precedence to the expression. The way you do that is to put the expression in some expected form, like post/pre/in-fix and provide an evaluation algorithm(post-fix ends up being pop(), pop(), evaluate(), push();. This requires that you check the individual tokens against a table that investigates the intersection of the operators and operands. It isn't anything you can do quickly or easily.
The code I wrote relies that the given order of tags is "NUMBER" "MATH" "NUMBER" "MATH" "NUMBER" and it completely ignores operational rules in math. It is just an outline of what you could do, so you may have to fix it up a bit to do what you want.
I have not tested this file due to lack of time, so debug it if necessary!
import net.sprakle.homeAutomation.interpretation.tagger.tags.*;
import java.util.List;
import java.util.Arrays;
public class Math {
private Tag[] tags; //Stores the converted tags as a "MathTag"
//Requires an array of tags
public Math(Tag[] inputTags) {
tags = new MathTag[inputTags.length]; //create a new MathTag array
System.arraycopy(inputTags, 0, tags, 0, tags.length); //Convert Tag array to MathTag array
}
//returns a value based on the tags
//TODO: ADD MATHEMATICAL ORDER OF OPERATIONS!!!
public double performMath() {
double value = 0;//initial value to return
for (int i = 0; i < tags.length; i++) { //perform initial check of the phrase given
if (tags[i].getType() = TagType.NUMBER && !tags[i].getWasChecked() && i + 1 < tags.length) {
value = performOperation(i, value, Double.parseDouble(tags[i].getValue()), tags[i+1].getType());
} else if (tags[i].getType() = TagType.MATH && !tags[i].getWasChecked() && i + 1 < tags.length) {
value = performOperation(i, value, Double.parseDouble(tags[i + 1].getValue()), tag.getType()); //I'm not positive if this would not cause issues
}
}
}
//Perform individual operations given the index of the operation, value1, value2, and the operation type
//The order of the array "operations" must match the order of the operations in the switch statement.
public double peformOperation(int i, double value1, double value2, String operation) {
String[] operations = {"add", "subtract", "multiply", "divide", "pwr", "root"}; //Array of operations
List list = Arrays.asList(operations); //Not exactly effecient, used to check what operation to perform
switch (list.indexOf(operation)) { //Perform a task based on the operation
case 0: //Addition
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 + value2;
case 1: //Subtraction
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 - value2;
case 2: //Multiplication
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 * value2;
case 3: //Division
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 / value2;
case 4: //Power
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return value1 * value1;
case 5: //Square Root
tags[i].setChecked(true); //Number
tags[i + 1].setChecked(true); //Operation
return Math.sqrt(value1);
}
return error(); //Non-valid operation found
}
//Need some way to detect an error
public double error() {
return 0;
}
//Need some way to check if a tag was looked at before
class MathTag extends Tag {
protected static boolean wasChecked = false;
public void setChecked(boolean checked) {
wasChecked = true;
}
public boolean getWasChecked() {
return wasChecked;
}
}
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Write a program which checks an array of String contains valid numbers.If the string contains ".", convert it to Double, otherwise convert it to an Integer.Input should be array of string { "10.20", "123456", "12.invalid"}.
My problem is that 123456 is getting changed to double.I have to change it to int.Please help :(
public class Ch7LU3Ex1
{
public static void main(String[] args)
{
String[] str = new String []{"10.20","123456","12.invalid"};
int i,count=0;
try
{
for(i=0;i<3;i++)
{
int l = str[i].length();
for(int j=0;j<l;j++)
{
if(str[i].charAt(j)=='.')
{
count++;
}
else
{
continue;
}
}
if(count!=0)
{
double d = Double.parseDouble(str[i]);
System.out.println(d);
}
else
{
int e = Integer.parseInt(str[i]);
System.out.println(e);
}
}
}
catch(NumberFormatException e)
{
System.out.println("Invalid number");
}
}
}
if(str[i].indexOf('.') == -1) {
int e = Integer.parseInt(str[i]);
}
else {
double d = Double.parseDouble(str[i]);
}
This is much more elegant than all of your unneeded loops. Good luck!
To understand how this works, see the String API for indexOf().
As for the current way you are using, you need to reset the count to 0 in each iteration, else each of your values after first double value is found will be converted to double, since your count value is non-zero in every case.
So, in your first for loop, you need to reset the count at the start as follows: -
for(i=0;i<3;i++)
{
count = 0;
Now, you are really making your task complex. You don't need to use the count variable at all. Also, you don't need the nested loop there. You can do it simple one loop like this. Just don't work on individual characters on your own. Java library has methods which have already done it for you. Use them instead: -
for (String str: arr) {
if (str.contains(".")) {
double d = Double.parseDouble(str);
} else {
int i = Integer.parseInt(str);
}
}
The loop is used is called enhanced for-loop.
String#contains() method checks whether a string contains a certain character or not. Or, you can use String#indexOf() method to find the index of . in your string. And if it returns a positive value, then your string contains that character.
I wouldn't use a loop at all. I would assume you don't have random data and you know the type of each "column" should be.
String[] str = {"10.20", "123456", "12.invalid"};
double d = Double.parseDouble(str[0]);
int i = Integer.parseInt(str[1]);
String s = str[2];
If you don't know if a value should be a double or an int, you can always parse it as a double without loss of precision.
It seems you have to set count back to zero for each string and you are not doing it.
After one iteration set again count to zero count=0 , in your second iteration count is not zero hence again consider as a double value
You have to reset your count variable to 0 after every examined element. This way count is incremented since "10.20" includes a dot and is not reset for "123456".
Your code is a bit of a mess, but the point is that you don't reset your count for each member of the str.
So if you add a counter=0; in the loop that goes trough all the characters of one string, you'd probably get what you want?
some extra tips:
use readable variable names
indent your code
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);