Как правильно представлять номера телефонов? - PullRequest
38 голосов
/ 14 августа 2010

У меня проблемы с представлением номера мобильного телефона в одном из моих приложений.

Мне было интересно, существует ли класс Integer, который позволит вам хранить такое число, начиная с 0417254482. Возможно, с использованием строкибыть более подходящим?В настоящее время, когда я пытаюсь использовать представление телефонного номера с целыми числами, удваивает длинные, я, кажется, храню случайные числа, а не числа, которые я намеревался хранить.

Ответы [ 8 ]

111 голосов
/ 14 августа 2010

Используйте String. Помимо всего прочего, вы не сможете хранить начальные нули, если будете использовать целые числа. Вы определенно не должны использовать int (слишком мало) float или double (слишком большой риск потери данных - см. Ниже); long или BigInteger могут быть подходящими (кроме проблемы начальных нулей), но, честно говоря, я бы пошел с String. Таким образом, вы можете также сохранять любые введенные пользователем тире или пробелы, чтобы было легче запомнить номер, если хотите.

С точки зрения "потери данных", упомянутой выше для float и double - float, определенно не хватает точности; double может работать, если вы счастливы, что вам никогда не понадобится больше 16 цифр (на пару меньше, чем у вас с long), но вам нужно быть очень, очень осторожным, чтобы где угодно вы конвертируете значение обратно из double в string, вы получите точное значение. Многие преобразования форматирования дадут вам приближение, которое может быть точным, скажем, до 10 значащих цифр - но вам нужно точное целое число. По сути, использование числа с плавающей запятой для телефонных номеров является принципиально плохой идеей. Если у вас есть для использования числового типа фиксированной ширины, используйте long, но в идеале избегайте его полностью.

35 голосов
/ 14 августа 2010

Подумайте об этом: действительно ли номер телефона - это номер? Имеет ли смысл добавлять (или делать другую арифметическую операцию) номера телефонов? Телефонные номера - это коды, они обычно обозначаются цифрами, но это всего лишь соглашение, и, может быть, в другой стране также используются буквы (я только что понял, как насчет международных телефонных номеров? У них есть + на начало. Вам нужно подумать о природе вещей, которые вы хотите изобразить, а затем найти наиболее подходящее представление.

3 голосов
/ 05 июля 2018

Если вы хотите провести валидацию и нормализацию, вы, вероятно, захотите использовать библиотеку, которая сделает это за васhttps://github.com/googlei18n/libphonenumber является одним из наиболее распространенных вариантов.

3 голосов
/ 14 августа 2010

Хотя телефонные номера являются именованными номерами, они обычно не являются номерами (например, ведущие нули, префикс страны + XX, ...).

Таким образом, есть две возможности правильно представить номер телефона в программе:

  1. Использование String для сохранения целого числа, как введено.
  2. Использование пользовательского типа данных, который обеспечивает дополнительную поддержку функций телефонных номеров

    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;
        }
    }
    

Действительно интересно посмотреть на все соглашения, которые используются на международном уровне

3 голосов
/ 14 августа 2010

Создайте свой собственный класс PhoneNumber с закрытым полем типа String для его представления.

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

Вы также можете представить номер с помощью long или BigInteger, если все номера телефонов имеют одинаковую длину, но будьте осторожны с начальными нулями.

Телефонный номер не является целым числом (или строкой). Это нечто, что должно иметь свой собственный класс.

EDIT: еще одна вещь: я бы не реализовал установщик для этого класса, потому что объект телефонного номера был бы лучше неизменным

2 голосов
/ 04 декабря 2015

Вы должны использовать строку или более специализированную структуру данных.

Основная причина в том, что операции, которые вы можете выполнять над телефонными номерами, являются лексикографическими, а не арифметическими. например Можно сказать, что номера телефонов для Франции начинаются с +33, но вы не можете предполагать, что они находятся в числовом диапазоне.

Эти другие аргументы недействительны по моему мнению

  • номер телефона может включать * или #. Эти символы можно передавать по телефонным линиям, но они не являются частью самого телефонного номера, и я считаю, что он выходит за рамки.
  • номер телефона может начинаться с начальных нулей . Местные телефонные номера могут, но они представляют собой ограниченное представление в первую очередь. Международные телефонные номера начинаются с кода страны, и ни один из них не имеет начального нуля. Следовательно, ни у одного международного номера телефона нет ведущих нулей.
  • номер телефона начинается с + . Число может прекрасно представлять это, просто будучи положительным. Также начиная с + это просто представление чисел E164, чтобы их можно было отличить от локальных чисел. Они действительно не должны, если вы только манипулируете числами E164.
  • номер телефона может содержать пробелы или скобки . Это абсурдно, потому что это просто текстовое представление числа. Вы не должны хранить это, так как люди могут иметь разные личные предпочтения для отдельных групп цифр (., -, и т. Д.).
0 голосов
/ 14 августа 2010

Вы должны использовать строку для поддержки чисел с ведущими нулями. Код, который вы указали, был:

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 
}

В конструкторе число является строкой, но когда вы вызываете конструктор, вы используете int для номера телефона. Я думаю, что в Java произошла ошибка компиляции. Это тот же код, который вы скомпилировали?

0 голосов
/ 14 августа 2010

Каждое число имеет бесконечное количество нулей слева и справа,

Чтобы представить это, вы должны использовать форматирование строки

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());
    }
}

Использовано% 010d среднее % [Argument_index $] [флаги] [ширина] [. Точность] преобразование

флаг 0 - заполнение нулями 10 - количество дополняющих нулей d - десятичное целое число

Реализация интерфейса Comparable даст вам возможность сортировки списка.

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);
  }

Выход

 0000000000 
 0000000123
 0000000124
 0000000125
 0000000126
 0000123777

Сопоставимые String Formatter

...