12

There are some situation that I need to convert string to float or some other numerical data-type but there is a probability of getting some nonconvertible values such as "-" or "/" and I can't verify all the values beforehand to remove them. and I want to avoid using try/catch for this matter , is there any other way of doing a proper conversion in java? something similar to C# TryParse?

14
  • why the artificial constraint on no exceptions? AFAIK, you'll have to roll your own! Commented Dec 2, 2011 at 20:18
  • Look at stackoverflow.com/a/1102916/1071777 The isNumeric method by CraigTP will basically be the tryParse (you can modify it according to your needs) Commented Dec 2, 2011 at 20:20
  • 4
    @Nim, you would be wrong about the "much quicker" claim, if you keep in mind coming from a C# perspective. float.TryParse is orders of magnitude faster when dealing with an improper input. Exception handling is slow, and we also do not like relying upon exceptions for control flow. So since Austin is coming from a C# perspective, he's looking for that same fast, non-exceptional validation of the input while simultaneously providing the output. You only learn that it does not exist in Java by seeking guidance! Commented Dec 2, 2011 at 20:35
  • 1
    @Nim, why would you think TryParse in .NET comes with a lot of overhead? Have you run profiling comparisons for the happy path and exceptional paths between the various number parsing techniques in order to come away with that conclusion, or are you merely assuming? Commented Dec 2, 2011 at 22:03
  • 2
    @Nim, that goes back to the second part. If I'm validating user input, I'm not going to let an exception drive my decision making. That's making exceptions part of the control flow, and that's bad programming practice in .NET. Again, if you're in an environment that does not have this approach, you use the tools you have. In .NET, we have TryParse, and it's fast, functional, and entirely appropriate for its typical usage. Your environment may differ, just as Java obviously does. Commented Dec 2, 2011 at 23:41

5 Answers 5

6

The simplest thing I can think of is java.util.Scanner . However this approach requires a new Scanner instance for each String.

String data = ...;
Scanner n = new Scanner(data);
if(n.hasNextInt()){//check if the next chars are integer
  int i = n.nextInt();   
}else{

}

Next you could write a regex pattern that you use to check the String (complex to fail too big values) and then call Integer.parseInt() after checking the string against it.

Pattern p = Pattern.compile("insert regex to test string here");
String data = ...;
Matcher m = p.matcher(data);
//warning depending on regex used this may 
//only check part of the string
if(m.matches()){
  int i = Integer.parseInt(data);
}

However both of these parse the string twice, once to test the string and a second time to get the value. Depending on how often you get invalid strings catching an exception may be faster.

Sign up to request clarification or add additional context in comments.

6 Comments

and the regex is "((-|\\+)?[0-9]+(\\.[0-9]+)?)+"
I'm sorry, but I would argue that the regular expression check approach will be slower than simply catching a parse exception, seems like premature optimization to me.
@Nim thats why I wrote last sentence and most likely the reason why java does not have a try parse, its slower when most values are valid.
In case anyone in the future wants a good solution for doubles, here's the regex for that: ^[-+]?[0-9]*\.?[0-9]+$ and it wont allow for anything else in the string to be anything but numbers (so don't worry about the warning comment in the code above)
Not sure if apache just uses a try-catch but for anyone looking here who just wants a utility method, there is NumberUtils.toInt(str, defaultValue): commons.apache.org/proper/commons-lang/javadocs/api-3.3.2/org/…
|
5

Unfortunately, there is no such method in Java. There is no out parameter in Java, so writing such a method would need to return a null Float to signal an error, or to pass a FloatHolder object which could be modified by the method:

public class FloatHolder {
    private float value;

    public void setValue(float value) {
        this.value = value;
    }

    public float getValue() {
        return this.value;
    }
}

public static boolean tryParseFloat(String s, FloatHolder holder) {
    try {
        float value = Float.parseFloat(s);
        holder.setValue(value);
    }
    catch (NumberFormatException e) {
        return false;
    }
}

4 Comments

my point is : avoid using try/catch for parse such simple values , yet thanks for the approach
Except by reimplementing parseFloat yourself, you won't be able to do it. If all your code uses the tryParseFloat method, it doesn't have to deal with exceptions. Only tryParseFloat does.
can you not use a Float? (my java is a little rusty) - what's with the FloatHolder?
You can use a Float and return null to signal an error. I suggested it in my answer. The FloatHolder is a way to have a signature similar to C#'s TryParse method.
2

This is an old question, but since all the answers fail to mention this (and I wasn't aware of it myself until seeing it in a merge request written by a colleague), I want to point potential readers to the Guava Floats and Ints classes:

With the help of these classes, you can write code like this:

    Integer i = Ints.tryParse("10");
    Integer j = Ints.tryParse("invalid");
    Float f = Floats.tryParse("10.1");
    Float g = Floats.tryParse("invalid.value");

The result will be null if the value is an invalid int or float, and you can then handle it in any way you like. (Be careful to not just cast it to an int/float, since this will trigger a NullPointerException if the value is an invalid integer/floating point value.)

Note that these methods are marked as "beta", but they are quite useful anyway and we use them in production.

For reference, here are the Javadocs for these classes:

Comments

1

Java does not provide some built in tryParse type of methods, on of the solutions you can try is to create your own tryParse Method and put try/catch code in this method and then you can easily use this method across your application very easily and without using try/catch at all the places you use the method.

One of the sample functions can have following code

public static Long parseLong(String value) {

        if(isNullOrEmpty(value)) {
            return null;
        }

        try {
            return Long.valueOf(value);
        }
        catch (NumberFormatException e) {
        }

        return null;
    }

Comments

0

Regular expressions helped me solve this issue. Here is how:

  1. Get the string input.
  2. Use the expression that matches one or more digits.
  3. Parse if it is a match.
String s = "1111";
int i = s.matches("^[0-9]+$") ? Integer.parseInt(s) : -1;
if(i != -1)
  System.out.println("Integer");
else
  System.out.println("Not an integer");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.