it-swarm.com.ru

Как правильно представлять номера телефонов?

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

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

37
user420344

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

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

108
Jon Skeet

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

35
manolowar

Хотя телефонные номера являются именованными номерами, они обычно не являются номерами (например, начальные нули, префикс страны + 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
Johannes Wachter

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

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

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

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

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

3
snakile

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

2
Tpt

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

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

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

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

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

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

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 означает % [Arguments_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

СравнимоФормататор строк

0
Damian Leszczyński - Vash

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

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
Hari Menon