Saral Saxena
Saral Saxena

Reputation: 121

Validating int and float value all together

I am getting a value named amount in an object through its getter as shown below.

Let's say the object is h then

h.getAmount()

Now I need to develop a validator that will validate that amount should be of type integer and if it is not then it will throw the exception, I have developed that also as shown below

private  boolean isint (String amount){
    boolean isValid = true;
    try {
        Integer.parseInt(amount); 
    }
    catch(NumberFormatException e){
        isValid = false;
    }
     return isValid;
}

Now the issue is that amount coming from h is an integer such as 1234, but it can also be a float such as 1258.26. So in the case of float it throws a NumberFormatException.

How could I make it perfect for both the values whether it is integer or whether it is float?

Upvotes: 3

Views: 13388

Answers (5)

Andrea Ligios
Andrea Ligios

Reputation: 50261

As suggested, it would be better to use long and double instead of int and float.

By the way, can't you simply check for a float ? If it is an int, than it can always be a float, potentially rounded with loss of precision.

public static boolean isFloat(String number){
    try {
       return !new Float(number).isNaN();
    } catch (NumberFormatException e){
        return false;
    }
}

Running demo: https://ideone.com/UpGPsK

Output:

> 1234                 IS     a valid Integer or Float    
> 1234.56              IS     a valid Integer or Float    
> 1234.56.78           IS NOT a valid Integer or Float     
> abc                  IS NOT a valid Integer or Float     
> 2147483647           IS     a valid Integer or Float    
> 3.4028235E38         IS     a valid Integer or Float    
> -2147483648          IS     a valid Integer or Float    
> 1.4E-45              IS     a valid Integer or Float

Upvotes: 1

Thomas W
Thomas W

Reputation: 14164

If you're talking about integers or a few decimals, you're probably talking about money or quantities, for which BigDecimal is ideal; and floating-point not really so good (due to rounding errors).

Otherwise, you're talking about a double floating-point value.

new BigDecimal( str) will parse an integer or decimal for you, but it will also accept exponents; eg 1.4E2 means 140.

Perhaps you want to use a regex pattern to validate it first;

if (! str.matches( "[-+]?(\\d+)|(\\d*\\.\\d+)")) 
    throw new NumberFormatException();

This pattern accepts decimals without any leading digits, such as .14159 -- which should be allowable.

Upvotes: 0

Rahul
Rahul

Reputation: 45070

You could use a regex like this:-

if (str.matches("[-+]?[0-9]*\\.?[0-9]+")) { // You can use the `\\d` instead of `0-9` too!
    // Is a number - int, float, double         
}

[-+]? - For the sign.

[0-9]*\.?[0-9]+ - For the numbers and the decimal point between them.

Update:-

In case exponential needs to be handled too, then the below regex can be used.

String regex = "[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?";

Upvotes: 3

Dariusz
Dariusz

Reputation: 22271

First of all, if you have a function called isInt it should do exactly that -- check if it's an integer. No more and no less.

You could try something like that

enum VarType {
    INTEGER, FLOAT, STRING, EMPTY
}

private VarType getVarType(String amount){
     if (amount.length() ==0) {
       return VarType.EMPTY;
     }
     if (amount.contains(".")) { 
       try {
         Float.parseFloat(amount); 
       }
       catch(NumberFormatException e){
         return ValType.STRING;
       }
       return ValType.FLOAT;
     } else {
       try {
         Integer.parseInt(amount); 
       }
       catch(NumberFormatException e){
         return ValType.STRING;
       }
       return ValType.INTEGER;
     }
}

I would not recommend it though, because using exceptions in this way is really expensive. Exceptions should be used as their name suggests, to handle special cases, exceptions, and not as a standard flow.

I would do it like this:

public class ParseVarTest {

    static enum VarType {
        INTEGER, FLOAT, STRING, EMPTY
    }

    private static VarType getVarType(String amount){
        boolean onlyDigits = true;
        int dotCount = 0;
        if (amount == null) {
            return VarType.EMPTY;
        }
        String trimmed = amount.trim();
        if (trimmed.length() == 0) {
            return VarType.EMPTY;
        }
        int a=0;
        if (trimmed.charAt(0) == '-') {
            a++;
        }
        for (int max=trimmed.length(); a<max; a++) {
            if ( trimmed.charAt(a) == '.' ) {
                dotCount++;
                if (dotCount>1) break;
            } else if ( !Character.isDigit(trimmed.charAt(a)) ) {
                onlyDigits = false;
                break;
            }  
        }

        if (onlyDigits) {
            if (dotCount ==0) {
                return VarType.INTEGER;
            } else if (dotCount ==1) {
                return VarType.FLOAT;
            } else {
                return VarType.STRING;
            }
        }
        return VarType.STRING;
    }

    public static void main(String[] args) {
        String[] vars = {"", "  ", "123", "-5123", "1234.41", "-1234.41", "-1234..41","a12312", "523sdf234sdf.123"};
        for (String var: vars) {
            System.out.print(var);
            System.out.print(": \t");
            System.out.println(getVarType(var));
        }
    }

}

It's quite long for such a simple task, but:

  • no regexes

  • at most a single scan of the string

  • readable (IMO)

  • fast

However, this solution does not validate the range of the value. String 10000000000 would still be recognized as a VarType.INTEGER even though the value could not fit into an int variable in Java.

Upvotes: 3

xagyg
xagyg

Reputation: 9721

Use Double.parseDouble ... (method name changed to isNumber to better reflect the meaning of the method) ...

private  boolean isNumber (String amount){
    boolean isValid = true;
    try {
        Double.parseDouble(amount); 
    }
    catch(NumberFormatException e){
        isValid = false;
    }
     return isValid;
}

... and could simplify to ...

private  boolean isNumber (String amount){
    try {
        Double.parseDouble(amount);             
    }
    catch(NumberFormatException e){
        return false;            
    }
    return true;
}

Upvotes: 1

Related Questions