web-dev-qa-db-fra.com

Quelle est la bonne façon de représenter les numéros de téléphone?

Je ne parviens pas à représenter un numéro de mobile dans l'une de mes applications.

Je me demandais s'il existe une classe Integer qui vous permettra de stocker un tel numéro commençant par 0417254482. Peut-être que l'utilisation d'une chaîne de caractères serait plus appropriée? les doubles longs me semblent stocker des nombres aléatoires et non les nombres que je voulais stocker.

37
user420344

Utilisez String. En dehors de toute autre chose, vous ne pourrez pas stocker de zéros non significatifs si vous utilisez des entiers. Vous certainement ne devez pas utiliser int (trop petit) float ou double (risque de perte de données trop important - voir ci-dessous); long ou BigInteger pourrait convenir (à part le problème des zéros non significatifs), mais franchement, je choisirais String. De cette façon, vous pouvez aussi stocker tous les tirets ou les espaces entrés pour faciliter la mémorisation du numéro, si vous le souhaitez.

En termes de "perte de données" mentionnée ci-dessus pour float et double - float n'a certainement pas assez de précision; doublepourrait travailler si vous êtes satisfait de n'avoir jamais besoin de plus de 16 chiffres (un couple de moins que vous obtenez avec long), mais vous devez faire très attention à ce que vous convertissiez la valeur n'importe où De retour de double à string, vous avez la valeur exacte. De nombreuses conversions de formatage vous donneront une approximation qui peut être exacte, par exemple, à 10 chiffres significatifs - mais vous voudriez un entier exact. Fondamentalement, utiliser une virgule flottante pour les numéros de téléphone est une idée fondamentalement mauvaise. Si vous devez pour utiliser un type numérique à largeur fixe, utilisez un long, mais idéalement, évitez-le complètement.

108
Jon Skeet

Pensez à ceci: un numéro de téléphone est-il vraiment un numéro? Est-il judicieux d'ajouter (ou d'effectuer une autre opération arithmétique) des numéros de téléphone? Les numéros de téléphone sont des codes, ils sont généralement représentés par des chiffres, mais ce n'est qu'une convention et, peut-être, dans un autre pays, les lettres d'utilisation aussi (je viens de me rendre compte, qu'en est-il des numéros de téléphone internationaux? Elles ont un + au début. Vous devez réfléchir à la nature des choses que vous voulez représenter, puis trouver la représentation la plus appropriée.

35
manolowar

Bien que les numéros de téléphone soient des numéros nommés, ils ne le sont généralement pas (par exemple, zéros à gauche, préfixe de pays + XX, ...).

Il existe donc deux possibilités pour représenter un numéro de téléphone correctement dans un programme:

  1. Utilisez String pour conserver le nombre entier comme entré.
  2. Utilisation d'un type de données personnalisé offrant une prise en charge supplémentaire des fonctionnalités de numéro de téléphone

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

C'est vraiment intéressant de regarder toutes les différentes conventions utilisées à l'international

3
Johannes Wachter

Créez votre propre classe PhoneNumber avec un champ privé de type String pour la représenter.

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

Vous pouvez également représenter le numéro avec long ou BigInteger si tous les numéros de téléphone ont la même longueur, mais faites attention aux zéros non significatifs. 

Un numéro de téléphone n'est pas vraiment un entier (ou une chaîne). C'est quelque chose d'autre qui devrait avoir une classe à part.

EDIT: Encore une chose: je n’implémenterais pas de passeur pour cette classe car un objet de numéro de téléphone serait mieux immuable

3
snakile

Si vous souhaitez effectuer la validation et la normalisation, vous voudrez probablement vous fier à une bibliothèque qui le fait pour vous. https://github.com/googlei18n/libphonenumber est l’une des options les plus courantes.

2
Tpt

Vous devez utiliser une chaîne ou une structure de données plus spécialisée.

La raison principale en est que les opérations que vous pouvez effectuer sur les numéros de téléphone sont lexicographiques et non arithmétiques . Vous pouvez dire que les numéros de téléphone pour la France commencent par +33, mais vous ne pouvez pas supposer qu'ils se trouvent dans une plage numérique.

Ces autres arguments ne sont pas valables à mon avis

  • un numéro de téléphone peut inclure * ou #. Ces symboles peuvent être transportés sur des lignes téléphoniques, mais ils ne font pas partie du numéro de téléphone lui-même, et j'estime qu'il est hors de portée.
  • un numéro de téléphone peut commencer par des zéros non significatifs . Les numéros de téléphone locaux peuvent, mais ils sont une représentation limitée en premier lieu. Les numéros de téléphone internationaux commencent par un indicatif de pays et aucun d'entre eux ne comporte un zéro non significatif. Par conséquent, aucun numéro de téléphone international ne comporte de zéros à gauche.
  • un numéro de téléphone commence par + . Un nombre peut parfaitement représenter cela, simplement en étant positif. Commencer également par + est simplement une représentation des numéros E164, de sorte qu'ils puissent être distingués des numéros locaux. Ce n’est vraiment pas nécessaire, si vous ne manipulez que les numéros E164.
  • un numéro de téléphone peut contenir des espaces ou des parenthèses . C'est absurde, car il ne s'agit que d'une représentation textuelle du nombre. Vous ne devriez pas stocker ceci, car les gens peuvent avoir différentes préférences personnelles pour séparer les groupes de chiffres (., -, , etc.).
2
rds

Chaque nombre a une quantité infinie de zéros à gauche et à droite, 

Pour le représenter, vous devez utiliser un formatage de chaîne 

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

Conversion de% 010d moyenne utilisée % [Index_argument $] [drapeaux] [largeur] [. Précision]

indicateur 0 - zéros de remplissage 10 - nombre de zéros de remplissage d - entier décimal

La mise en œuvre de l'interface Comparable vous donne la possibilité de trier la liste. 

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

La sortie est 

 0000000000 
 0000000123
 0000000124
 0000000125
 0000000126
 0000123777

ComparableFormateur de chaînes

Vous devez utiliser une chaîne pour prendre en charge les nombres avec des zéros non significatifs. Le code que vous avez fourni était:

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 
}

Dans le constructeur, le numéro est une chaîne, mais lorsque vous appelez le constructeur, vous utilisez un int pour un numéro de téléphone. Il doit y avoir une erreur de compilation ici en Java, je pense. Est-ce le même code que vous avez compilé?

0
Hari Menon