Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java流:groupingBy和flatMapping键_Java_Java Stream_Flatmap - Fatal编程技术网

Java流:groupingBy和flatMapping键

Java流:groupingBy和flatMapping键,java,java-stream,flatmap,Java,Java Stream,Flatmap,假设我有一个国家/地区对象列表,其中包含该国家/地区使用的语言列表,如下所示: 国家级{ 列出语言; } 我想创建以下格式的地图: 映射,使每种语言映射到国家/地区对象列表。例如: "French" -> [Country:France, Country:Canada], "English" -> [Country:UK, Country:US] 性能是这里的一个问题,所以我希望避免多次迭代和查找。我尝试过使用groupingBy,但是如何

假设我有一个国家/地区对象列表,其中包含该国家/地区使用的语言列表,如下所示:

国家级{
列出语言;
}
我想创建以下格式的地图:
映射
,使每种语言映射到国家/地区对象列表。例如:

"French" -> [Country:France, Country:Canada],
"English" -> [Country:UK, Country:US]
性能是这里的一个问题,所以我希望避免多次迭代和查找。我尝试过使用
groupingBy
,但是如何
flatMap
键集

例如,这将导致
Map

countries.stream()
.collect(Collectors.groupingBy(country->country.getLanguages(),toList());
这样就可以了:

countries.stream()
.flatMap(国家->国家.getLanguages()
.stream()
.map(lang->new SimpleEntry(lang,
新的ArrayList(Arrays.asList(country‘‘‘‘)’)
.collect(collector.toMap)(
条目::getKey,
条目::getValue,
(l1,l2)->{
l1.addAll(l2);
返回l2;
}));

由于您似乎关心性能,因此不要将流用于此简单任务:

Map<String, List<Country>> countriesByLanguage = new HashMap<>();
for (Country country : countries) {
    for (String language : country.getLanguages()) {
        countriesByLanguage.computeIfAbsent(language, k -> new ArrayList<>())
                           .add(country);
    }
}
Map countriesByLanguage=newhashmap();
适用于(国家:国家){
for(字符串语言:country.getLanguages()){
countriesByLanguage.computeIfAbsent(语言,k->new ArrayList())
.添加(国家);
}
}
您可以按如下方式使用流中的流进行操作:首先迭代国家列表,然后迭代嵌套的语言列表,准备
«语言,国家»
对,然后收集它们以绘制地图:

publicstaticvoidmain(字符串[]args){
列表国家=列表国家/地区(
新国家(“法国”,法国名单),
新国家(“加拿大”,“法国”),
新国家(“英国”,名单(“英语”),
新国家(“美国”,英文名单);
Map=countries.stream()
//溪流
.flatMap(country->country.getLanguages().stream())
.map(lang->map.entry(lang,country)))
.collect(collector.toMap)(
//关键语言
Map.Entry::getKey,
//价值清单
entry->new ArrayList(List.of(entry.getValue()),
//合并重复项(如果有)
(列表1、列表2)->{
列表1.addAll(列表2);
返回列表1;
}
));
//输出
map.forEach((k,v)->System.out.println(k+“=”+v));
//英语=[国家:英国,国家:美国]
//法语=[国家:法国,国家:加拿大]
}
静态类国家/地区{
字符串名;
列出语言;
公共国家/地区(字符串名称、列表语言){
this.name=名称;
这个。语言=语言;
}
公共列表getLanguages(){
返回语言;
}
@凌驾
公共字符串toString(){
返回“国家:+名称;
}
}

如果我用一个大数据集一次性调用流,它不是会更快吗?如果我多次调用它,只会慢一些,因为它有更多的开销?@Edwin为什么你认为流比普通循环快?流的开销会使它变慢。在这种特殊情况下,流需要创建中间对象(例如,
SimpleEntry
),因此会产生垃圾,这也是一个需要考虑的问题。除此之外,我发现这里的非流解决方案更简单。所以,仅仅因为你可以使用流,并不意味着你应该这样做。流是伟大的,但它们不是所有问题的答案。你介意详细介绍一下ComputeFabSent的使用吗?如果存在一个密钥,这里会发生什么?如何将其添加到列表中?@Edwin为什么我需要详细说明?文件还不够吗?我最初把它读作:
countriesByLanguage.computeIfAbsent(language,k->newarraylist().add(country))这相当混乱,但这显然是最好的解决方案,谢谢。