Is there a better, more elegant (and/or possibly faster) way than
boolean isNumber = false;
try{
Double.valueOf(myNumber);
isNumber = true;
} catch (Nu
If you want something that's blisteringly fast, and you have a very clear idea of what formats you want to accept, you can build a state machine DFA by hand. This is essentially how regexes work under the hood anyway, but you can avoid the regex compilation step this way, and it may well be faster than a generic regex compiler.
I would use the Jakarta commons-lang, as always ! But I have no idea if their implementation is fast or not. It doesnt rely on Exceptions, which might be a good thig performance wise ...
I don't believe there's anything built into Java to do it faster and still reliably, assuming that later on you'll want to actually parse it with Double.valueOf (or similar).
I'd use Double.parseDouble instead of Double.valueOf to avoid creating a Double unnecessarily, and you can also get rid of blatantly silly numbers quicker than the exception will by checking for digits, e/E, - and . beforehand. So, something like:
public boolean isDouble(String value)
{
boolean seenDot = false;
boolean seenExp = false;
boolean justSeenExp = false;
boolean seenDigit = false;
for (int i=0; i < value.length(); i++)
{
char c = value.charAt(i);
if (c >= '0' && c <= '9')
{
seenDigit = true;
continue;
}
if ((c == '-' || c=='+') && (i == 0 || justSeenExp))
{
continue;
}
if (c == '.' && !seenDot)
{
seenDot = true;
continue;
}
justSeenExp = false;
if ((c == 'e' || c == 'E') && !seenExp)
{
seenExp = true;
justSeenExp = true;
continue;
}
return false;
}
if (!seenDigit)
{
return false;
}
try
{
Double.parseDouble(value);
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
Note that despite taking a couple of tries, this still doesn't cover "NaN" or hex values. Whether you want those to pass or not depends on context.
In my experience regular expressions are slower than the hard-coded check above.
You could use a regex, i.e. something like String.matches("^[\\d\\-\\.]+$");
(if you're not testing for negative numbers or floating point numbers you could simplify a bit).
Not sure whether that would be faster than the method you outlined though.
Edit: in the light of all this controversy, I decided to make a test and get some data about how fast each of these methods were. Not so much the correctness, but just how quickly they ran.
You can read about my results on my blog. (Hint: Jon Skeet FTW).
See java.text.NumberFormat (javadoc).
NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
Number myNumber = nf.parse(myString);
int myInt = myNumber.intValue();
double myDouble = myNumber.doubleValue();
Use StringUtils.isDouble(String)
in Apache Commons.