What's the right way to represent phone numbers?

岁酱吖の 提交于 2019-11-26 11:22:30

Use String. Aside from anything else, you won't be able to store leading zeroes if you use integers. You definitely shouldn't use int (too small) float or double (too much risk of data loss - see below); long or BigInteger could be appropriate (aside from the leading zeroes problem), but frankly I'd go with String. That way you can also store whatever dashes or spaces the user has entered to make it easier to remember the number, if you want to.

In terms of the "data loss" mentioned above for float and double - float definitely doesn't have enough precision; double could work if you're happy that you'll never need more than 16 digits (a couple fewer than you get with long) but you would need to be very, very careful that anywhere you convert the value back from double to string, you got the exact value. Many formatting conversions will give you an approximation which may be accurate to, say, 10 significant digits - but you'd want an exact integer. Basically, using floating point for phone numbers is a fundamentally bad idea. If you have to use a fixed-width numeric type, use a long, but ideally, avoid it entirely.

Think about this: Is a phone number really a number? Does it make sense adding (or make another arithmetic operation) with phone numbers? Phone numbers are codes, they're usually represented with numbers, but that's just a convention and, maybe, in another country the use letters too (I've just realized, what about international phone numbers? they have a + at the beginning. You have to think about the nature of the things you want to represent, and then, find the most suitable representation.

Create your own PhoneNumber class with a private field of type String to represent it.

public class PhoneNumber {
   private String number;
   public PhoneNumber(String number) {
      //check validity of number
      this.number = number;
   }
   //getter, comparator, etc...
}

You could also represnt the number with long or BigInteger if all phone numbers have the same length, but be careful with leading zeros.

A phone number is not really an integer (or a string). It is something else which shuld have a class of its own.

EDIT: one more thing: I wouldn't implement a setter for this class because a phone number object would better be immutable

Johannes Wachter

Although phone numbers are named numbers, they are normally not numbers (e.g. leading zeros, country prefix +XX, ...).

So there are two possibilities to represent a phone number correctly inside a program:

  1. Using String to keep the whole number like entered.
  2. Using a custom data type that offers additional support for phone number features

    public class PhoneNumber implements Comparable<PhoneNumber>{
    
        private String countryCode;
    
        private String areaCode;
    
        private String subscriberNumber;
    
        // Constructor(s)
    
        // Getter
    
        // HashCode + Equals
    
        // compareTo
    
        @Override
        public String toString(){
            return countrycode + " " + areaCode + " " + subscriberNumber;
        }
    }
    

It's really interesting to look at all the different conventions that are used internationally

If you want to do validation and normalization you probably want to rely on a library that does it properly for you. https://github.com/googlei18n/libphonenumber is one of the most common options.

You should use a string or a more specialized data structure.

The main reason is that the operations that you can do on phone numbers are lexicographic, and not arithmetic. e.g. You can say that phone numbers for France start with +33, but you cannot assume they are in a numerical range.

These other arguments are not valid in my opinion

  • a phone number can include * or #. This symbols can be transported on phone lines, but they are not part of the phone number itself, and I consider it's out of scope.
  • a phone number can start with leading zeros. Local phone numbers can, but they are a limited representation in the first place. International phone numbers start with a country code, and none of them has a leading zero. Hence no international phone number has leading zeros.
  • a phone number starts with +. A number can perfectly represent this, by simply being positive. Also starting with + is just a representation of E164 numbers, so that they can be distinguished from local numbers. They really don't have to, if you only manipulate E164 numbers.
  • a phone number can contain spaces or parentheses. This is absurd, because it's just textual representation of the number. You shouldn't store this as people can have different personal preferences to separate groups of digits (., -, , etc.).

You should use string to support numbers with leading zeros. The code you provided was:

Order order1 = new PickUpOrder(orderTime, 0473519954); 
//The pickup order requires an orderTime (String) and a contact number(Int). Heres    
//the constructor for PickUpOrder. 

public PickUpOrder(Date orderTime, String number) 
{ 
    discount = .2; 
    phoneNumber = number; 
    super.setOrderTime(orderTime); 
    //Test print 
    System.out.println(phoneNumber) 
    //reads int as 74049273 instead of 0473519954 
}

In the constructor, the number is string but when you call the constructor you used an int for phone number. There must have been a compile error here in java I think. Is this the same code you compiled?

Every number have infinity amount of zeros on the left and right side,

To represent it you should use a string formating

class PhoneNumber implements Comparable<PhoneNumber> {

    private Long number;

    public PhoneNumber(Long number) {
        this.number = number;
    }

    public Long getNumber() {
        return this.number;
    }

    public boolean equals(Object object) {

        if (getNumber() == null && object == null) {
            return true; //or false its depend 
        }

        return getNumber().equals(object);
    }

    public int compareTo(PhoneNumber that) {

            if(that == null) {
             return -1;
            }

        Long thisNumber = getNumber();
            Long thatNumber = that.getNumber();

        if (thisNumber == null && thatNumber == null) {
            return 0; //or -1
        }

        if (thisNumber == null && thatNumber != null) {
            return -1;
        }

        return thisNumber.compareTo(thatNumber);

    }

    @Override
    public String toString() {
        return String.format("%010d", getNumber());
    }
}

Used %010d mean %[argument_index$][flags][width][.precision]conversion

flag 0 - padding zeros 10 - amount of padding zeros d - decimal integer

The implementation of interface Comparable give you the posibility to sort List.

List<PhoneNumber> phoneNumbers = new ArrayList();
 phoneNumbers.add(new PhoneNumber (123L);
 phoneNumbers.add(new PhoneNumber (123777L);
 phoneNumbers.add(new PhoneNumber (125L);
 phoneNumbers.add(new PhoneNumber (124L);
 phoneNumbers.add(new PhoneNumber (126L);

Collections.sort(phoneNumbers);

  for(PhoneNumber phoneNumber : phoneNumbers) {
   System.Console.Out.WriteLine(phoneNumber);
  }

The output is

 0000000000 
 0000000123
 0000000124
 0000000125
 0000000126
 0000123777

Comparable String Formatter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!