I'm new, basic conversion question

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Iuri234
    New Member
    • Jan 2009
    • 2

    I'm new, basic conversion question

    hello.

    I'd like to ask how to determine if a String could also be an Integer:
    I have to determine from, say "boo" "b123" "20" "132" which are numbers.

    thanks..
  • cordeo
    New Member
    • Jul 2008
    • 16

    #2
    Have a look at Java 2 Platform SE v1.3.1: Class Integer)

    and catch the NumberFormatExc eption which will by thrown if the string does not contain a parsable integer.

    Comment

    • Iuri234
      New Member
      • Jan 2009
      • 2

      #3
      thanks a lot.. I made it so, in a try{}, and works fine:

      Code:
      if (args[i].compareTo(Integer.toString(Integer.parseInt(args[i]))) == 0)
      but is there any other way which is more simple?

      Comment

      • cordeo
        New Member
        • Jul 2008
        • 16

        #4
        There is no need for conversion back to String and doing a comparison with compareTo. An elegant solution is like this:
        Code:
                // Loop through all the command line arguments
                for (int i = 0; i < args.length; i++) {
                    // Get the command line parameter as a String
                    String potentialNumber = args[i];
                    
                    // Stores the parsed command line argument
                    int j;
                    
                    try {
                        // Try to read the argument as an integer
                        j = Integer.parseInt(potentialNumber);
                    } catch (NumberFormatException e) {
                        // Output an error message on the console
                        System.out.println
                            ( "Argument " + i
                            + " is not an integer "
                            + "(" + e.getMessage() + ")!"
                            );
                        
                        // Continue from for (line 2 above) with
                        // the next command line argument
                        continue;
                    }
                    
                    // No exception was thrown, so
                    // we have found an integer
                    System.out.println
                        ( "Argument " + i
                        + " is a fine integer number: " + j
                        );
                }
        Last edited by cordeo; Jan 26 '09, 10:23 AM. Reason: Wrong rendering of code

        Comment

        • BSCode266
          New Member
          • Jan 2007
          • 38

          #5
          If you want to make sure there are no letters or any other symbols I would suggest the use of a method in the Character wrapper class.

          Example:
          Code:
          //Loop just as the previous example to go through all args.
          for (int i = 0; i < args.length; i++) {
               //Temporary String to save the digits in.
               String temp;
          
               //Loop through a single args.
               for(int j = 0; j < args[i].length(); j++){
                    //Check for digits in the whole args[i].
                    if(Character.isDigit(args[i].charAt(j))){
                         //Add the found digit to the temporary String.
                         temp += args[i].charAt(j);
                    }
               }
               try{
                    int x = Integer.parseInt(temp);
               }catch (NumberFormatException e) {
                //See previous example.
               }
          }

          Comment

          • JosAH
            Recognized Expert MVP
            • Mar 2007
            • 11453

            #6
            Originally posted by BSCode266
            If you want to make sure there are no letters or any other symbols I would suggest the use of a method in the Character wrapper class.
            That approach doesn't work; although the String "99999999999999 9999999" contains all digits, it is not an integer in Java's terms (too big to fit in four bytes).

            kind regards,

            Jos

            Comment

            • cordeo
              New Member
              • Jul 2008
              • 16

              #7
              The approach does work, but integer is (of course) limited to at most Integer.MAX_VAL UE. If you need support for larger numbers, use Long (Long (Java Platform SE 6)) or even BigInteger (BigInteger (Java Platform SE 6)).

              Long is also limited, but can hold larger numbers than integer. BigInteger is not limited at all, but needs more memory.

              The class Long has a parseLong method. BigInteger has no such method, but you can use
              Code:
              new BigInteger("999999999999999999999");

              Comment

              • JosAH
                Recognized Expert MVP
                • Mar 2007
                • 11453

                #8
                Originally posted by cordeo
                The approach does work, but integer is (of course) limited to at most Integer.MAX_VAL UE.
                Yup, and the op wanted to know whether or not a String could textually represent an Integer (see the first post). Your approach doesn't check that.

                kind regards,

                Jos

                Comment

                • cordeo
                  New Member
                  • Jul 2008
                  • 16

                  #9
                  Originally posted by JosAH
                  Yup, and the op wanted to know whether or not a String could textually represent an Integer (see the first post). Your approach doesn't check that.
                  This sounds quite strange. I'm afraid I don't understand you. BSCode266 suggests possible extra constraints, but keeps this line (from my original code example):
                  Originally posted by BSCode266
                  15. int x = Integer.parseIn t(temp);
                  Integer.parseIn t() will never accept anything that does not fit an Integer, and absolutely performs the required check. I really don't understand why you think my approach doesn't check that. Try it yourself: your input string "99999999999999 9999999" will be refused by my own code example as well as by the code example of BSCode266 (in both cases, Integer.parseIn t throws a NumberFormatExc eption).

                  For the case you (or possibly the original poster) deliberately want(s) larger (mathematical) integer numbers, I suggested Long and BigInteger as alternatives.

                  A problem with the approach of BSCode266 is that he silently ignores non-digit characters, so "23abc4" will be accepted as 234, which is incorrect. The scoping is incorrect as well. int x = Integer.parseIn t... is inside the try-block and cannot be referenced after the try. That is why I placed the int j; declaration before try.

                  Comment

                  • JosAH
                    Recognized Expert MVP
                    • Mar 2007
                    • 11453

                    #10
                    Originally posted by cordeo
                    This sounds quite strange. I'm afraid I don't understand you. BSCode266 suggests possible extra constraints, but keeps this line (from my original code example):

                    Integer.parseIn t() will never accept anything that does not fit an Integer
                    You're right: I misread your and other replies; I apologize for that; imho it is silly to explicitly check for digits and optionally discard the non-digits. Simply feed the String to the Integer.parseIn t() method and let it throw an exception when needed.

                    kind regards,

                    Jos

                    Comment

                    • chaarmann
                      Recognized Expert Contributor
                      • Nov 2007
                      • 785

                      #11
                      Simple Reguar expressions make your life easier

                      Originally posted by cordeo
                      A problem with the approach of BSCode266 is that he silently ignores non-digit characters, so "23abc4" will be accepted as 234, which is incorrect.
                      Yes, he should break the loop at the first non-digit he found. I guess he wants to simulate other languages like C++ which will stop parsing when they find a non-digit and return the converted number at string begin (in this case 23).

                      But what he probably also should care about are 2 more cases:
                      a) Leading and trailing spaces. Integer.parseIn t(" 017") and Integer.parseIn t("017 ") throws an exception. So you should probably trim the string.
                      b) hexadecimal and octal numbers. Integer.parseIn t("017") returns 17, but it is an octal number, because it begins with a leading zero. So the correct answer would be 15. Maybe you should think of also allowing hexadecimal numbers, like "0x1a".

                      Use of regular expressions to shorten algorithm:
                      Originally posted by BSCode266
                      Code:
                      ...
                          //Loop through a single args.
                           for(int j = 0; j < args[i].length(); j++){
                                //Check for digits in the whole args[i].
                                if(Character.isDigit(args[i].charAt(j))){
                                     //Add the found digit to the temporary String.
                                     temp += args[i].charAt(j);
                                }
                           }
                      ...
                      A nasty thing of this loop is that it unnecessarily creates and allocates many temporary strings in memory. Consider StringBuilder class (or StringBuffer for older JDKs).

                      Anyway, there is no need to make a loop and parse for characters, you can do it simpler in a single line with help of regular expression:
                      Code:
                      String temp = args[i].replaceFirst("([URL="file://\\d"]\\d[/URL]*).*", "$1")

                      Comment

                      • cordeo
                        New Member
                        • Jul 2008
                        • 16

                        #12
                        Originally posted by JosAH
                        imho it is silly to explicitly check for digits and optionally discard the non-digits. Simply feed the String to the Integer.parseIn t() method and let it throw an exception when needed.
                        I fully agree. That is what I posted originally, and also why I noticed a problem in the approach of BSCode266.

                        On the other hand, I think it is useful to understand that Integer.parseIn t() uses the Character class internally anyway.

                        Comment

                        • cordeo
                          New Member
                          • Jul 2008
                          • 16

                          #13
                          Suggestion a) is nice. Concerning regular expressions, they might not be very suitable for the original poster (who was not even familiar with parseInt). Let's not make it too difficult for some who is new to Java.

                          Originally posted by chaarmann
                          b) hexadecimal and octal numbers. Integer.parseIn t("017") returns 17, but it is an octal number, because it begins with a leading zero. So the correct answer would be 15. Maybe you should think of also allowing hexadecimal numbers, like "0x1a",
                          017 as octal number and 0x1a as hexadecimal number are valid when directly written in Java. For example, a ==b, a == c and b == c after these 3 lines of code:
                          Code:
                              int a = 017;
                              int b = 0xf;
                              int c = 15;
                          That is quite different from Integer.parseIn t(String) which is documented to only work with base-10 numbers. For octal and hexadecimal numbers, there is Integer.parseIn t(String, int), but though leading zero's are accepted, the 'x' of hexadecimal numbers is not, so a special check is necessary.

                          There is
                          -3 // decimal, accepted by parseInt
                          +4 // decimal, accepted by parseInt
                          245 // decimal, accepted by parseInt
                          -03 // octal, accepted by parseInt
                          +04 // octal, accepted by parseInt
                          0245 // octal, accepted by parseInt
                          -0x3 // hex, not accepted by parseInt ('x' not allowed)
                          +0x4 // hex, not accepted by parseInt ('x' not allowed)
                          0x245 // hex, not accepted by parseInt ('x' not allowed)

                          Code:
                                      // Get the command line parameter as a String
                                      String potentialNumber = args[i];
                                      
                                      // Stores the parsed command line argument
                                      int j;
                                      
                                      try {
                                          if (potentialNumber.length() == 0) {
                                              throw new NumberFormatException("Empty string!");
                                          }
                                          
                                          // Start at index 0
                                          int idx = 0;
                                          
                                          // Skip (for now) leading + or - sign
                                          char first = potentialNumber.charAt(0);
                                          if (first == '+' || first == '-') {
                                              idx++;
                                          }
                                          
                                          if (potentialNumber.charAt(idx) == '0') { // Octal or Hex?
                                              idx++;
                                              if (potentialNumber.charAt(idx) == 'x') { // Hex?
                                                  idx++;
                                                  // parseInt can't handle the 'x', so we only provide
                                                  // everything after the 'x' to parseInt
                                                  j = Integer.parseInt
                                                          (potentialNumber.substring(idx), 16);
                                                  // We possibly skipped a - sign, so check for that
                                                  if (first == '-') {
                                                      j *= -1;
                                                  }
                                              } else { // Octal
                                                  // parseInt can handle the complete octal
                                                  // potentialNumber, including a possible + or - sign.
                                                  j = Integer.parseInt(potentialNumber, 8);
                                              }
                                          } else {
                                              // Try to read the argument as a decimal integer
                                              // parseInt can handle the complete decimal
                                              // potentialNumber, including a possible + or - sign.
                                              j = Integer.parseInt(potentialNumber);
                                          }
                                      } catch (NumberFormatException e) {
                                          // Output an error message on the console
                                      }

                          Comment

                          Working...