23

I have a list which will store Number objects. The list will be populated by parsing a list of strings, where each string may represent any subclass of Number.

How do I parse a string to a generic number, rather than something specific like an integer or float?

Matt
  • 11,157
  • 26
  • 81
  • 110
  • Does it have to be international form with commas too? – Justin Thomas Nov 27 '11 at 15:38
  • I had exactly this requirement not long ago. We didn't find a solution that I really liked. We considered all of the currently posted answers. Andrew's presupposes that we know the expected format, which wasn't true for us. Justin's doesn't cover different decimal separators (as his comment implies). AlexR's covers things pretty well. But using try/catch blocks for basic logic flow is often frowned on. I'm very intrigued to see if there is a reasonably common and elegant solution to this. – mdahlman Nov 27 '11 at 15:51
  • @mdahlman True for using Integer, but using NumberFormat does not. – Andrew Nov 27 '11 at 15:55

6 Answers6

47

Number cannot be instantiated because it is an abstract class. I would recommend passing in Numbers, but if you are set on Strings you can parse them using any of the subclasses,

Number num = Integer.parseInt(myString);

or

Number num = NumberFormat.getInstance().parse(myNumber);

@See NumberFormat

Andrew
  • 13,757
  • 13
  • 66
  • 84
  • Hmm... this might be the most promising for my (similar? identical?) issue. The "Integer" part isn't flexible enough. But perhaps the "NumberFormat" idea is perfect. – mdahlman Nov 27 '11 at 16:07
  • I think this is what I need, but did you mean `parse(myNumber)` instead of `format(myNumber)`? (so that it returns a Number not a String) – Matt Nov 27 '11 at 16:29
  • @Andrew: is it safe as compare to returning float with small 'f' or int? –  Jun 06 '15 at 12:54
  • parse(myNumber) also parses e.g. "2-5", which is actually not a number! Check JavaDoc: "The method may not use the entire text of the given string.". https://docs.oracle.com/javase/7/docs/api/java/text/NumberFormat.html#parse(java.lang.String) – Martin Oct 19 '20 at 16:41
  • Caution: [`NumberFormat.getInstance()`](https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/text/NumberFormat.html#getInstance()) "Returns a general-purpose number format for the current **default FORMAT locale**." This may or may not be what you need, but be aware that whether `2.000` is parsed as `2` or `2000` depends on your locale... – Hulk Jan 15 '21 at 14:40
7

You can use the java.text.NumberFormat class. This class has a parse() method which parses given string and returns the appropriate Number objects.

        public static void main(String args[]){
            List<String> myStrings = new ArrayList<String>(); 
            myStrings.add("11");
            myStrings.add("102.23");
            myStrings.add("22.34");

            NumberFormat nf = NumberFormat.getInstance();
            for( String text : myStrings){
               try {
                    System.out.println( nf.parse(text).getClass().getName() );
               } catch (ParseException e) {
                    e.printStackTrace();
               }
           }
        }
Drona
  • 6,886
  • 1
  • 29
  • 35
  • 2
    This also works with international number formats like 1'234.56, 1,234/56, 1 234,56, 1 234-56 etc. – Drona Nov 27 '11 at 16:36
5

you can obtain Number from String by using commons.apache api -> https://commons.apache.org/proper/commons-lang/javadocs/api-3.4/index.html

Usage:

String value = "234568L";  //long in the form string value
Number number = NumberUtils.createNumber(value);
Venks
  • 386
  • 3
  • 7
4

Something like the following:

private static Number parse(String str) {
    Number number = null;
    try {
        number = Float.parseFloat(str);
    } catch(NumberFormatException e) {
        try {
            number = Double.parseDouble(str);
        } catch(NumberFormatException e1) {
            try {
                number = Integer.parseInt(str);
            } catch(NumberFormatException e2) {
                try {
                    number = Long.parseLong(str);
                } catch(NumberFormatException e3) {
                    throw e3;
                }       
            }       
        }       
    }
    return number;
}
adam
  • 1,067
  • 11
  • 24
AlexR
  • 114,158
  • 16
  • 130
  • 208
2

A simple way is just to check for dot Pattern.matches("\\."). If it has a dot parse as Float.parseFloat() and check for exception. If there is an exception parse as Double.parseDouble(). If it doesn't have a dot just try to parse Integer.parseInt() and if that fails move onto Long.parseLong().

Justin Thomas
  • 5,680
  • 3
  • 38
  • 63
1
Integer.valueOf(string s)

returns an Integer object holding the value of the specified String.

Integer is specialized object of Number

Max
  • 842
  • 5
  • 16