Группировка потоков по первым 3 символам - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть список телефонных номеров, которые я использовал для группировки по национальным (немецкие номера) / международным (остальные страны). Пример списка выглядит так:

List<String> list = new ArrayList<>();
list.add("+4969123");
list.add("+4989123");
list.add("+4930123");
list.add("+4365013");
list.add("+4369923");
list.add("+4365023");
list.add("+4176123");
list.add("+4178123");
list.add("+4179123");
list.add("+447782");
list.add("+447903");
list.add("+447701");

и метод для группировки по префиксу "+49"

public static Map<Boolean,List<String>> national_International_Map(List<String> list){
    return list.stream().collect(Collectors.groupingBy(s -> s.startsWith("+49")));
}

, тогда я не могу вызвать метод с true или false, чтобы получить разделенные числа на национальный / международный

List<String> nationalNums      = national_International_Map(list).get(true);
List<String> internationalNums = national_International_Map(list).get(false);

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

public static Map<Boolean,List<String>> countryMap(List<String> list, String country){
    switch(country){
        case "de": return list.stream().collect(Collectors.groupingBy(s -> s.startsWith("+49")));
        case "at": return list.stream().collect(Collectors.groupingBy(s -> s.startsWith("+43")));
        case "ch": return list.stream().collect(Collectors.groupingBy(s -> s.startsWith("+41")));
        case "uk": return list.stream().collect(Collectors.groupingBy(s -> s.startsWith("+44")));
        default:   return null;
    }
}

и назовите его следующим образом:

List<String> ukNums = countryMap(list,"uk").get(true);
List<String> chNums = countryMap(list,"ch").get(true);

Может кто-нибудь сказать мне, как мне лучше всего это сделать - может быть, без расширения блока переключателей все время? Я хотел бы иметь что-то вроде:

List<String> ukNums = countryMap(list).get("uk");

1 Ответ

2 голосов
/ 01 апреля 2020

Если вы определили метод getCountryFromPhone, вы можете сгруппировать телефонные номера по их стране с помощью метода groupingBy, который вы использовали до сих пор:

Map<String, List<String>> groupedPhones = list.stream().collect(Collectors.groupingBy(s -> getCountryFromPhone(s)));

Затем вы можете получить телефонные номера Великобритании как вы хотите: groupedPhones.get("uk")

Теперь, как выглядит getCountryFromPhone? Он должен вернуть код страны для телефонного номера, поэтому для начинающих будет работать следующее.

static Map<String,String> phoneMap = Map.of(
    "+49", "de",
    "+43", "at",
    "+41", "ch",
    "+44", "uk");

private static String getCountryFromPhone(String s) {
    return phoneMap.getOrDefault(s.substring(0, 3), "unknown");
}

Позже вам может понадобиться добавить поддержку для стран с телефонными кодами стран различной длины. Это не тривиальная вещь, и есть библиотеки типа libphonenumber , чтобы помочь с этим. Вы бы просто заставили getCountryFromPhone вызвать соответствующий метод в библиотеке.

...