按前 3 个字符进行流分组
Stream grouping by first 3 chars
我有一个 phone 号码列表,我曾将其按国内(德国号码)/国际(世界其他地区)分组。示例列表如下所示:
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");
如果您定义 getCountryFromPhone
方法,则可以使用您目前使用的 groupingBy 方法按国家/地区对 phone 个号码进行分组:
Map<String, List<String>> groupedPhones = list.stream().collect(Collectors.groupingBy(s -> getCountryFromPhone(s)));
然后您可以按照自己的方式获得英国 phone 号码:groupedPhones.get("uk")
现在,getCountryFromPhone
是什么样子的?它应该 return phone 号码的国家/地区代码,因此以下内容适用于初学者。
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");
}
稍后,您可能需要添加对 phone 不同长度国家/地区代码的国家/地区的支持。这不是一件小事,有像 libphonenumber 这样的库可以帮助解决这个问题。您只需让 getCountryFromPhone
调用库中的适当方法即可。
我有一个 phone 号码列表,我曾将其按国内(德国号码)/国际(世界其他地区)分组。示例列表如下所示:
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");
如果您定义 getCountryFromPhone
方法,则可以使用您目前使用的 groupingBy 方法按国家/地区对 phone 个号码进行分组:
Map<String, List<String>> groupedPhones = list.stream().collect(Collectors.groupingBy(s -> getCountryFromPhone(s)));
然后您可以按照自己的方式获得英国 phone 号码:groupedPhones.get("uk")
现在,getCountryFromPhone
是什么样子的?它应该 return phone 号码的国家/地区代码,因此以下内容适用于初学者。
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");
}
稍后,您可能需要添加对 phone 不同长度国家/地区代码的国家/地区的支持。这不是一件小事,有像 libphonenumber 这样的库可以帮助解决这个问题。您只需让 getCountryFromPhone
调用库中的适当方法即可。