web-dev-qa-db-ja.com

電話番号を表す正しい方法は何ですか?

アプリケーションの1つで携帯電話番号を表すことができません。

0417254482で始まるそのような数値を格納できるIntegerクラスがあるのだろうかと思っていました。おそらく文字列を使用する方が適切でしょうか?現在、intを使用して電話番号を表現しようとすると、倍の長さで、保存するつもりの番号ではなく、乱数を保存するように見えます。

40
user420344

Stringを使用します。他のこととは別に、整数を使用する場合、先行ゼロを格納することはできません。 間違いなくint(小さすぎる)floatまたはdouble(データ損失のリスクが大きすぎる-以下を参照)を使用しないでください。 longまたはBigIntegerが適切な場合があります(先行ゼロ問題は別として)が、率直に言ってStringを使用します。そうすれば、alsoユーザーが入力したダッシュやスペースを保存して、必要に応じて番号を覚えやすくすることができます。

floatおよびdoubleについて上記で説明した「データ損失」に関しては、floatには十分な精度がありません。 doublecould 16桁以上(longで得られる数より少ない数)が必要ないことに満足している場合は動作しますが、値をdoubleからstringに戻すどこでも、正確な値が得られるように、非常に注意してください。多くのフォーマット変換では、たとえば有効数字10桁まで正確な近似値が得られますが、正確な整数が必要です。基本的に、電話番号に浮動小数点を使用することは根本的に悪い考えです。 haveで固定幅の数値型を使用する場合は、longを使用しますが、理想的には完全に避けてください。

114
Jon Skeet

これについて考えてみましょう:電話番号は本当に番号ですか?電話番号を追加する(または別の算術演算を行う)のは理にかなっていますか?電話番号はコードであり、通常は数字で表されますが、これは単なる慣習であり、おそらく他の国では使用文字もあります(国際電話番号はどうですか?+最初。表現したいものの性質について考え、次に最も適切な表現を見つけなければなりません。

36
manolowar

電話番号は名前付きの番号ですが、通常は番号ではありません(たとえば、先行ゼロ、国のプレフィックス+ XX、...)。

そのため、プログラム内で電話番号を正しく表すには2つの可能性があります。

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

すべての異なる 国際的に使用される慣習 を見るのは本当に興味深いです

4

検証と正規化を行いたい場合は、おそらく適切にそれを行うライブラリに依存する必要があります。 https://github.com/googlei18n/libphonenumber は、最も一般的なオプションの1つです。

3
Tpt

String型のプライベートフィールドを使用して、それを表す独自のPhoneNumberクラスを作成します。

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

すべての電話番号の長さが同じ場合、longまたはBigIntegerを使用して番号を表すこともできますが、先行ゼロには注意してください。

電話番号は実際には整数(または文字列)ではありません。 shuldが独自のクラスを持っている他の何かです。

編集:もう一つ:電話番号オブジェクトは不変であるため、このクラスにはセッターを実装しません

3
snakile

文字列またはより特殊なデータ構造を使用する必要があります。

主な理由は、電話番号に対して実行できる操作は辞書式であり、算術演算ではないことです。例えばフランスの電話番号は+33で始まると言うことができますが、数値範囲内にあると想定することはできません。

これらの他の議論は私の意見では無効です

  • 電話番号には*または#を含めることができます。この記号は電話回線で転送できますが、電話番号自体の一部ではないため、範囲外と考えています。
  • 電話番号は先頭にゼロを付けることができます。ローカル電話番号は可能ですが、そもそもそれらは限定的な表現です。国際電話番号は国コードで始まり、先頭にゼロがない番号があります。したがって、先頭にゼロが付いている国際電話番号はありません。
  • 電話番号は+で始まります。数字は、単に正であることによって、これを完全に表すことができます。また、+で始まるのはE164番号の単なる表現であるため、ローカル番号と区別できます。 E164番号のみを操作する場合、それらは本当に必要ありません。
  • 電話番号にはスペースまたは括弧を含めることができます。これは数字の単なるテキスト表現であるため、ばかげています。数字のグループ(.-など)ごとに個人の好みが異なる場合があるため、これを保存しないでください。
2
rds

文字列を使用して、先行ゼロ付きの数値をサポートする必要があります。あなたが提供したコードは:

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