Как правильно представлять номера телефонов?
У меня проблемы с отображением номера мобильного телефона в одном из моих приложений.
Мне было интересно, если есть класс Integer, который позволит вам хранить такое число, начиная с 0417254482. Возможно, использование строки будет более подходящим? В настоящее время, когда я пытаюсь использовать представление телефонного номера с целыми числами, удваивает длинные, я, кажется, храню случайные числа, а не числа, которые я намеревался хранить.
9 ответов
Использование String
, Помимо всего прочего, вы не сможете хранить начальные нули, если будете использовать целые числа. Вы определенно не должны использовать int
(слишком маленький) float
или же double
(слишком большой риск потери данных - см. ниже); long
или же BigInteger
может быть целесообразным (кроме проблемы с ведущими нулями), но, честно говоря, я бы пошел с String
, Таким образом, вы также можете сохранить любые введенные пользователем тире или пробелы, чтобы было легче запомнить номер, если хотите.
В терминах "потери данных", упомянутых выше для float
а также double
- float
определенно не хватает точности; double
может работать, если вы счастливы, что вам никогда не понадобится больше 16 цифр (на пару меньше, чем вы получаете с long
) но вам нужно быть очень, очень осторожным, чтобы в любом месте вы конвертировали значение обратно из double
в string
, вы получили точное значение. Многие преобразования форматирования дадут вам приблизительное значение, которое может быть, скажем, до 10 значащих цифр, но вам нужно точное целое число. По сути, использование плавающей запятой для телефонных номеров является в корне плохой идеей. Если вам нужно использовать числовой тип с фиксированной шириной, используйте long
, но в идеале, избегайте этого полностью.
Подумайте об этом: действительно ли номер телефона - это номер? Имеет ли смысл добавлять (или делать другую арифметическую операцию) с номерами телефонов? Телефонные номера - это коды, они обычно обозначаются цифрами, но это всего лишь соглашение, и, может быть, в другой стране также используются буквы (я только что понял, как насчет международных телефонных номеров? +
в начале. Вы должны подумать о природе вещей, которые вы хотите представить, а затем найти наиболее подходящее представление.
Если вы хотите провести валидацию и нормализацию, вы, вероятно, захотите использовать библиотеку, которая сделает это за вас. https://github.com/googlei18n/libphonenumber - один из наиболее распространенных вариантов.
Хотя телефонные номера являются именованными номерами, они обычно не являются номерами (например, начальные нули, префикс страны +XX, ...).
Таким образом, есть две возможности правильно представить номер телефона внутри программы:
- С помощью
String
сохранить весь номер как введено. Использование пользовательского типа данных, который предлагает дополнительную поддержку функций телефонных номеров
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; } }
Это действительно интересно взглянуть на все различные соглашения, которые используются на международном уровне
Создайте свой собственный класс PhoneNumber с закрытым полем типа String для его представления.
public class PhoneNumber {
private String number;
public PhoneNumber(String number) {
//check validity of number
this.number = number;
}
//getter, comparator, etc...
}
Вы также можете представить номер с помощью long или BigInteger, если все номера телефонов имеют одинаковую длину, но будьте осторожны с начальными нулями.
Номер телефона на самом деле не является целым числом (или строкой). Это что-то еще, что должно иметь свой собственный класс.
РЕДАКТИРОВАТЬ: еще одна вещь: я бы не реализовал установщик для этого класса, потому что объект номер телефона лучше было бы неизменным
Вы должны использовать строку или более специализированную структуру данных.
Основная причина заключается в том, что операции, которые вы можете выполнять над телефонными номерами, являются лексикографическими, а не арифметическими. Например, вы можете сказать, что номера телефонов для Франции начинаются с +33
, но вы не можете предполагать, что они находятся в числовом диапазоне.
Эти другие аргументы не действительны на мой взгляд
- номер телефона может включать
*
или же#
, Эти символы можно передавать по телефонным линиям, но они не являются частью самого телефонного номера, и я считаю, что это выходит за рамки. - номер телефона может начинаться с начальных нулей. Местные телефонные номера могут, но они представляют собой ограниченное представление в первую очередь. Международные телефонные номера начинаются с кода страны, и ни у одного из них нет начального нуля. Следовательно, ни у одного международного номера телефона нет ведущих нулей.
- номер телефона начинается с +. Число может прекрасно представлять это, просто будучи положительным. Также начиная с
+
это просто представление чисел E164, так что их можно отличить от локальных чисел. Они действительно не должны, если вы только манипулируете числами E164. - номер телефона может содержать пробелы или скобки. Это абсурдно, потому что это просто текстовое представление числа. Вы не должны хранить это, так как люди могут иметь разные личные предпочтения для отдельных групп цифр (
.
,-
,, так далее.).
Вы должны использовать строку для поддержки чисел с ведущими нулями. Код, который вы предоставили, был:
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 произошла ошибка компиляции. Это тот же код, который вы скомпилировали?
Каждое число имеет бесконечное количество нулей на левой и правой стороне,
Чтобы представить это, вы должны использовать форматирование строки
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 означает%[аргумент_индекса $][флаги] [ширина][. Точность] преобразования
флаг 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
Я бы предложил не использовать примитивный тип данных.
Причина: примитивы не могут принимать специальные символы, такие как +,-,(, и, ). Если вы принимаете телефонные номера в этом формате +1(xxx)-xxx-xxxx.