0

My Java application 'A' is getting mobile number as String from another java application. So after app A gets the mobile number string, I need to validate if that mobile number String has only numbers in it. For validating that I have used a simple logic as below,

public static boolean containsOnlyDigits(String str, int n) {
    for (int i = 1; i < n; i++) {
        if (!Character.isDigit(str.charAt(i))) {
            return false;
        }
    }
    return true;
}

I am checking from i=1 as 1st character will be '+' for country code. This approach is O(n). There is another approach where we can use Double.parseDouble(str). This will throw NumberFormatException so that we can catch and consider it is an Alphanumeric String.

Which of these approaches are best based on performance?

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
Sel_va
  • 588
  • 5
  • 25
  • in it's internals Double#parseDouble uses a loop with isDigit...But better write a JMH test to validate. – kofemann Oct 23 '20 at 10:18
  • 2
    “This approach is O(n)” — Of course it is. What’s the problem? – Konrad Rudolph Oct 23 '20 at 10:28
  • @KonradRudolph I want to know if we can use Double.parseDouble instead of using our own implementation and it's performance impact. – Sel_va Oct 23 '20 at 11:05
  • 1
    @Sel_va I still don’t understand this objection since `Double.parseDouble` is **obviously** also running in O(n) (how could it not?!), and so is every other conceivable method. – Konrad Rudolph Oct 23 '20 at 11:14
  • 1
    Mobile phone numbers can contain all sorts of characters that are numbers, most notable the `+`´sign as you have noted. But also whitespace, parentheses, slashes, dashes and a few other things. Are you sure you need the string to be purely numeric? – Polygnome Oct 23 '20 at 13:44
  • @Sel_va - If one of the answers resolved your issue, you can help the community by marking that as accepted. An accepted answer helps future visitors use the solution confidently. – Arvind Kumar Avinash Oct 25 '20 at 21:58

3 Answers3

1

You could try, remove the + if not useful:

 /**
 * Assuming that a phone number is of an international format, having `+` sign as prefix
 * and with no spaces in between the numbers, validates if a string is a valid phone number.
 * 
 * @param phone
 * @return resulting boolean
     */
private boolean isValidPhoneNumber(String phone) {
    if(phone == null) return false;
    
    return Pattern.matches("\\+\\d{11,15}", phone);
}
Aman
  • 1,627
  • 13
  • 19
0

I am checking from i=1 as 1st character will be '+' for country code.

You can use the regex, \+\d{n - 1} which means the first character is + and the remaining n - 1 characters are digits. It also means that the total length of the string should be n.

public class Main {
    public static void main(String[] args) {
        // Tests
        System.out.println(containsOnlyDigits("+123456789", 10));
        System.out.println(containsOnlyDigits("+123456789", 9));
        System.out.println(containsOnlyDigits("+123456789", 8));
        System.out.println(containsOnlyDigits("-123456789", 9));
        System.out.println(containsOnlyDigits("123456789", 9));
        System.out.println(containsOnlyDigits("ABC123456", 9));
    }

    public static boolean containsOnlyDigits(String str, int n) {
        String regex = "\\+\\d{" + (n - 1) + "}";
        return str.matches(regex);
    }
}

Output:

true
false
false
false
false
false
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
0

Using regular expressions is costly. For this reason, you can easily solve this problem using the lambda notation in Java 8.

boolean numericControl = str.chars().allMatch(x -> Character.isDigit(x));
  • 1
    Using regex isn’t *that* costly, especially with a precompiled regex, and it’s a perfectly appropriate solution for text input validation. In fact, creating streams is *also* costly. – Konrad Rudolph Oct 23 '20 at 10:35