Java 表示电话号码的正确方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3483156/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the right way to represent phone numbers?
提问by user420344
I'm having trouble representing a mobile number in one of my applications.
我在我的一个应用程序中表示手机号码时遇到问题。
I was wondering if there is an Integer class that will allow you to store such a number starting with 0417254482. Perhaps using a string be a more appropriate? At present when I'm trying to use represent a phone number with ints, doubles longs I seem to store random numbers and not the numbers I meant to store.
我想知道是否有一个 Integer 类可以让你存储这样一个以 0417254482 开头的数字。也许使用字符串更合适?目前,当我尝试使用 int 表示电话号码时,doubles longs 我似乎存储随机数而不是我打算存储的数字。
采纳答案by Jon Skeet
Use String
. Aside from anything else, you won't be able to store leading zeroes if you use integers. You definitelyshouldn'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 alsostore whatever dashes or spaces the user has entered to make it easier to remember the number, if you want to.
使用String
. 除此之外,如果您使用整数,您将无法存储前导零。你绝对不应该使用int
(太小)float
或double
(数据丢失风险太大 - 见下文);long
或者BigInteger
可能是合适的(除了前导零问题),但坦率地说,我会选择String
. 这样,如果您愿意,您还可以存储用户输入的任何破折号或空格,以便更轻松地记住数字。
In terms of the "data loss" mentioned above for float
and double
- float
definitely doesn't have enough precision; double
couldwork 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 haveto use a fixed-width numeric type, use a long
, but ideally, avoid it entirely.
就上面提到的“数据丢失”而言,float
和double
-float
绝对没有足够的精度;double
可如果你的工作很快乐,你永远不会需要超过16位(比你得到一对夫妇较少long
),但你必须非常,非常小心,任何地方,你将从值回double
给string
,你得到了确切的价值。许多格式转换会给你一个近似值,它可能精确到 10 位有效数字——但你需要一个精确的整数。基本上,对电话号码使用浮点数从根本上来说是个坏主意。如果您必须使用固定宽度的数字类型,请使用 a long
,但最好完全避免使用它。
回答by Damian Leszczyński - Vash
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
使用 %010d 表示 %[argument_index$][flags][width][.precision] 转换
flag 0 - padding zeros 10 - amount of padding zeros d - decimal integer
标志 0 - 填充零 10 - 填充零的数量 d - 十进制整数
The implementation of interface Comparable give you the posibility to sort List.
接口 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);
}
The output is
输出是
0000000000
0000000123
0000000124
0000000125
0000000126
0000123777
回答by snakile
Create your own PhoneNumber class with a private field of type String to represent it.
使用 String 类型的私有字段创建您自己的 PhoneNumber 类来表示它。
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.
如果所有电话号码的长度相同,您也可以使用 long 或 BigInteger 来表示号码,但要小心前导零。
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
编辑:还有一件事:我不会为这个类实现一个setter,因为电话号码对象最好是不可变的
回答by Hari Menon
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?
在构造函数中,数字是字符串,但是当您调用构造函数时,您使用 int 作为电话号码。我认为这里在java中一定有编译错误。这是您编译的相同代码吗?
回答by manolowar
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.
想一想:电话号码真的是一个数字吗?添加电话号码(或进行其他算术运算)是否有意义?电话号码是代码,它们通常用数字表示,但这只是一种惯例,也许在另一个国家/地区也使用字母(我刚刚意识到,国际电话号码怎么样?他们+
在开头有一个。你必须考虑你想要代表的事物的性质,然后找到最合适的代表。
回答by Johannes Wachter
Although phone numbers are named numbers, they are normally not numbers (e.g. leading zeros, country prefix +XX, ...).
尽管电话号码是命名号码,但它们通常不是数字(例如前导零、国家/地区前缀 +XX、...)。
So there are two possibilities to represent a phone number correctly inside a program:
因此,在程序中正确表示电话号码有两种可能性:
- Using
String
to keep the whole number like entered. 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; } }
- 使用
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; } }
It's really interesting to look at all the different conventions that are used internationally
回答by rds
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.
主要原因是您可以对电话号码进行的操作是按字典顺序排列的,而不是算术运算。例如,您可以说法国的电话号码以 开头+33
,但您不能假设它们在数字范围内。
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.).
- 电话号码可以包括
*
或#
。这个符号可以在电话线上传输,但它们不是电话号码本身的一部分,我认为它超出了范围。 - 电话号码可以以前导零开头。本地电话号码可以,但它们首先是有限的代表。国际电话号码以国家/地区代码开头,并且没有前导零。因此,没有国际电话号码有前导零。
- 电话号码以 + 开头。一个数字可以通过简单的正数来完美地表示这一点。同样开头
+
的只是 E164 号码的表示,以便可以将它们与本地号码区分开来。如果您只操作 E164 号码,他们真的不必这样做。 - 电话号码可以包含空格或括号。这是荒谬的,因为它只是数字的文本表示。你不应该存储这个作为的人可以有不同的个人喜好的数字单独组(
.
,-
,等)。
回答by Tpt
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/libphonenumberis one of the most common options.
如果您想进行验证和规范化,您可能需要依赖一个可以为您正确执行此操作的库。https://github.com/googlei18n/libphonenumber是最常见的选项之一。