2016-08-21 6 views
0

У меня есть мобильные номера в столбце таблицы базы данных, в формате country_code с последующим mobile_number формат Так Мобильный номер, как это,Удалить HashMap ключ из строки

+91123456789 // country code of India is +91 followed by mobile number 
+97188888888 // Country code of UAE +971 

У меня есть один HashMap, содержащий CountryCodes из 5 стран как это,

map.put("+91","India") 
map.put("+94","Sri Lanka") 
map.put("+881","Bangladesh") 
map.put("+971","UAE") 
map.put("+977","Nepal") 

Моя Bean структура что-то вроде этого

class UserDetails { 

    // other fields 
    String countryCode; 
    String mobileNumber; 
} 

Теперь моя задача - взять номер мобильного телефона из столбца таблицы базы данных и разделить его на две части и установить countryCode и mobileNumber, но длина кода страны (в ключе карты) варьируется от 3 до 4. Эта проверка может быть выполнена с использованием subString() и equals(), но я не думаю, что это правильно, так что будет изящным (может быть, проверка в map key) способом решения этой проблемы?

+0

Вы хотите сохранить разделенные номера в базе данных? И это будет одноразовая операция? – rohitvats

+0

Я не вижу никаких других решений. Вы не можете угадать информацию, которой у вас нет. – davidxxx

+0

@rohitvats Нет, цифры хранятся в объединенном формате, но у меня есть два двух элемента управления html для кода страны (выберите список), а другой - номер мобильного телефона (текстовое поле), поэтому для отображения сохраненных значений мне это нужно. – piechuckerr

ответ

1

ИМХО одна карта лучше. Пример;

public static void main(String args[]) throws Exception { 
    Map<String, String> map = new HashMap<>(); 
    put(map, "+91", "India"); 
    put(map, "+94", "Sri Lanka"); 
    put(map, "+881", "Bangladesh"); 
    put(map, "+971", "UAE"); 
    put(map, "+977", "Nepal"); 
    map = Collections.unmodifiableMap(map); 

    String mobileNumber = "+91123456789"; 
    System.out.println(countryCode(map.keySet(), mobileNumber)); 
} 

private static void put(Map<String, String> map, String key, String value) { 
    if (countryCode(map.keySet(), key) != null) { 
     throw new IllegalArgumentException("..."); 
    } 
    map.put(key, value); 
} 

public static String countryCode(Set<String> countryCodes, String number) { 
    if (number == null || number.length() < 3) { 
     throw new IllegalArgumentException("..."); 
    } 
    String code = number.substring(0, 3); 
    if (!countryCodes.contains(code)) { 
     if (number.length() > 3) { 
      code = number.substring(0, 4); 
      if (!countryCodes.contains(code)) { 
       code = null; 
      } 
     } else { 
      code = null; 
     } 
    } 
    return code; 
} 
+0

'map' - не лучшее имя для набора. И даже для карты это действительно не помогает понять, что содержит карта – Dici

+2

Плюс, тот же вопрос, что и для другого ответа: как вы знаете, что код из трех букв никогда не может быть префиксом каких-либо четырех буквенных кодов? Я бы предпочел иметь логику, используя общую длину номера телефона, чтобы определить длину кода – Dici

+0

@ Dici Я знаю это, я использовал собственные имена в своем реальном коде. – piechuckerr

0

Вы можете использовать две карты для кода страны различной длины, а затем искать сначала для матча с 3 буквами, а затем с 4 буквами.

HashMap<String, String > threeLetterCodes = new HashMap<String, String>(); 
    threeLetterCodes.put("+91","India"); 
    threeLetterCodes.put("+94","Sri Lanka"); 


    HashMap<String, String > fourLetterCodes = new HashMap<String, String>();   
    fourLetterCodes.put("+881","Bangladesh"); 
    fourLetterCodes.put("+971","UAE"); 
    fourLetterCodes.put("+977","Nepal"); 

    String test = "+97188888888"; 

    String prefix = test.substring(0, 3); 
    String country = threeLetterCodes.get(prefix); 
    if (country == null) { 
     prefix = test.substring(0, 4); 
     country = fourLetterCodes.get(prefix); 
    } 

    System.out.println(country); 

Выход:

UAE 
+2

Не думайте, что это проще, чем одна карта. Кроме того, гарантировано ли, что ни один буквенный код не является префиксом по меньшей мере одного 4-символьного кода? – Dici

+0

Хмм, да одна карта может быть использована здесь. Глядя на https://en.wikipedia.org/wiki/List_of_country_calling_codes, кажется, что предположение о том, что префикс из 3 букв никогда не является префиксом четырехбуквенного кода, является истинным. –

+0

Возможно, это является частью спецификации кодов стран, но это может быть и не так. Если бы я мог быть уверен, что никогда никогда не будет введен код с таким свойством, тогда это может быть безопаснее, но все же лучше, если мы можем избежать полагаться на предположения. – Dici

1

Хотя there is a library который seems to already do the trick, я думаю, что я бы для легкого самостоятельного решения написано:

import java.util.Arrays; 
import java.util.HashMap; 
import java.util.Map; 

public class CountryExtractor { 
    private static final Map<String, String> COUNTRY_MAPPING = new HashMap<>(); 

    static { 
     COUNTRY_MAPPING.put("+91", "India"); 
     COUNTRY_MAPPING.put("+94", "Sri Lanka"); 
     COUNTRY_MAPPING.put("+881", "Bangladesh"); 
     COUNTRY_MAPPING.put("+971", "UAE"); 
     COUNTRY_MAPPING.put("+977", "Nepal"); 
    } 

    public static void main(String[] args) { 
     String[] inputs = new String[] { "+91123456789", "+97188888888" }; 

     for (String input : inputs) { 
      System.out.println(Arrays.toString(parseNumber(input))); 
     } 
    } 

    private static String[] parseNumber(String number) { 
     for (String countryCode : COUNTRY_MAPPING.keySet()) { 
      if (number.startsWith(countryCode)) { 
       return new String[] { countryCode, number.replace(countryCode, "") }; 
      } 
     } 
     return new String[0]; 
    } 
} 

Выход:

[+91, 123456789] 
[+971, 88888888] 

Обратите внимание, что это не может работать правильно, если мобильный префикс является подстрокой другого, но в соответствии с Wikipedia код страны, вызывающий код, prefix codes и, следовательно, гарантирует, что «нет целое кодовое слово в системе, которое является префиксом (начальным сегментом) любого другого кодового слова в системе ».

+1

Это неэффективный подход, поскольку вам нужно перебирать все коды стран в худшем случае. –

+0

@AshwineeKJha +1. Это медленно, хотя не должно быть сотен стран, вы как бы побеждаете цель карты – Dici

+0

Возможно. С другой стороны, это не требует дополнительной логики для обработки 1-значного, 2-значного, трехзначного или n-разрядного префикса. И если это окажется слишком неэффективным, я бы сказал, что ясность по крайней мере так же важна, как и эффективность. – Marvin

Смежные вопросы