[英]What's the right way to represent phone numbers?
我在我的一個應用程序中表示手機號碼時遇到問題。
我想知道是否有一個 Integer 類可以讓您存儲這樣一個以 0417254482 開頭的數字。也許使用字符串更合適? 目前,當我嘗試使用整數表示電話號碼時,我似乎存儲了隨機數而不是我打算存儲的數字。
使用String
。 除此之外,如果您使用整數,您將無法存儲前導零。 你絕對不應該使用int
(太小) float
或double
(數據丟失的風險太大 - 見下文); long
或BigInteger
可能是合適的(除了前導零問題),但坦率地說,我會選擇String
。 這樣,如果您願意,您還可以存儲用戶輸入的任何破折號或空格,以便更容易記住該數字。
就上面提到的float
和double
的“數據丟失”而言 - float
肯定沒有足夠的精度; 如果您很高興永遠不需要超過 16 位數字(比long
少幾位),那么double
可以工作,但是您需要非常非常小心,在任何地方將值從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 來表示號碼,但要注意前導零。
電話號碼並不是真正的整數(或字符串)。 它是其他東西,應該有自己的一類。
編輯:還有一件事:我不會為這個類實現一個setter,因為電話號碼對象最好是不可變的
您應該使用字符串或更專業的數據結構。
主要原因是您可以對電話號碼進行的運算是字典序的,而不是算術運算。 例如,您可以說法國的電話號碼以+33
開頭,但您不能假設它們在數字范圍內。
這些其他論點在我看來是無效的
*
或#
。 這個符號可以在電話線上傳輸,但它們不是電話號碼本身的一部分,我認為它超出了范圍。+
開頭的只是E164號碼的一種表示,以便與本地號碼區分開來。 如果您只操縱 E164 數字,他們真的不必這樣做。.
, -
,
, ETC。)。每個數的左右兩邊都有無數個零,
為了表示它,您應該使用字符串格式
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$][flags][width][.precision]conversion
標志 0 - 填充零 10 - 填充零的數量 d - 十進制整數
Comparable 接口的實現為您提供了對 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);
}
輸出是
0000000000
0000000123
0000000124
0000000125
0000000126
0000123777
您應該使用字符串來支持帶有前導零的數字。 您提供的代碼是:
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 中一定存在編譯錯誤。 這是你編譯的代碼嗎?
我建議不要使用原始數據類型。
原因:基元不能接受特殊字符,如+、-、(、和、)。 如果您接受這種格式的電話號碼+1(xxx)-xxx-xxxx 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.