I have a list of phone numbers, which I used to group by national (German numbers) / international (rest of the world). Example list looks like:
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");
and a method to group by the prefix "+49"
public static Map<Boolean,List<String>> national_International_Map(List<String> list){
return list.stream().collect(Collectors.groupingBy(s -> s.startsWith("+49")));
}
then I cann call the method with true or false to get the numbers separted to national/ international
List<String> nationalNums = national_International_Map(list).get(true);
List<String> internationalNums = national_International_Map(list).get(false);
But now the requirements have changed and I have to group the numbers by country. At the moment there are only four countries. But more may be added later. For this I have thought about the following, but it is complicated if I have to group more countries.
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;
}
}
and call it like:
List<String> ukNums = countryMap(list,"uk").get(true);
List<String> chNums = countryMap(list,"ch").get(true);
Can somebody tell me how I should do it best - maybe without extending the switch block all the time? I would like to have something like :
List<String> ukNums = countryMap(list).get("uk");
If you define a getCountryFromPhone
method, you can group phone numbers by their country with the groupingBy method you've been using so far:
Map<String, List<String>> groupedPhones = list.stream().collect(Collectors.groupingBy(s -> getCountryFromPhone(s)));
Then you can get the UK phone numbers the way you want: groupedPhones.get("uk")
Now, what does getCountryFromPhone
look like? It should return the country code for a phone number, so the following will work for starters.
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");
}
Later on, you may need to add support for countries with phone country codes of different length. This is not a trivial thing, and there are libraries like libphonenumber to help with this. You would just make your getCountryFromPhone
call the appropriate method in the library.