首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用java 8流将Map<File、File>转换为Map<File、List<File>>

使用java 8流将Map<File、File>转换为Map<File、List<File>>
EN

Stack Overflow用户
提问于 2018-04-06 14:32:04
回答 1查看 420关注 0票数 3

我有一些属性文件保存在Map中。示例:

代码语言:javascript
复制
Map<String, String> map = new HashMap<>();
map.put("1", "One");
map.put("2", "Two");
map.put("3", "Two");
map.put("4", "One"); 

我想将Map<String, String>转换为

代码语言:javascript
复制
Map<String, List<String>> map = new HashMap<>(); 

那应该是

代码语言:javascript
复制
<"One", ("1", "4")>
<"Two", ("2", "3")>

我有一些代码,我想用Java 8风格重写。

代码语言:javascript
复制
  private Map<File, List<File>> getAllFiles(Set<File> files) {
   Map<File, File> inputFilesWithTskFile = 
   AppStorage.getInstance().getApplicationBean().getInputFilesWithTskFile();

    List<File> tsks = new ArrayList<>();
    for (Map.Entry<File, File> entry : inputFilesWithTskFile.entrySet()) {
        if (files.contains(entry.getKey())) {
            tsks.add(entry.getValue());
        }
    }
    Map<File, List<File>> listTsk = new HashMap<>();
    for (Map.Entry<File, File> entry : inputFilesWithTskFile.entrySet()) {
        if (tsks.contains(entry.getValue())) {
            List<File> files1 = listTsk.get(entry.getValue());
            if (files1 == null) {
                files1 = new ArrayList<>();
            }
            files1.add(entry.getKey());
            listTsk.put(entry.getValue(), files1);
        }
    }
    return listTsk;
  }

谢谢你的帮助。也许您知道一些教程,这些教程解释如何从Map创建Map,地图左侧应该有值,右侧应该是按值分组的键列表。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-06 14:50:17

如下所示:

代码语言:javascript
复制
private Map<File, List<File>> getAllFiles(List<File> files) {
    return AppStorage.getInstance().getApplicationBean().getInputFilesWithTskFile()
            .entrySet()
            .stream()
            .filter(e -> files.contains(e.getKey()))
            .collect(groupingBy(Entry::getValue, mapping(Entry::getKey, toList())));
}

也就是说,获取所有的filesWithTskFile,过滤出键不在files中的Map中的条目。然后将Mapvalue分组。

使用

代码语言:javascript
复制
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;

一个更一般的例子,包括:

代码语言:javascript
复制
public static Map<String, List<String>> groupByValue(final Map<String, String> input) {
    return input.entrySet().stream()
            .collect(groupingBy(Entry::getValue, mapping(Entry::getKey, toList())));
}

跑步:

代码语言:javascript
复制
final Map<String, String> example = Map.of(
        "1", "A",
        "2", "B",
        "3", "A",
        "4", "B"
        );

groupByValue(example).forEach((k, v) -> System.out.printf("%s->%s%n", k, v));

给予:

代码语言:javascript
复制
A->[3, 1]
B->[2, 4]

扩大到:

代码语言:javascript
复制
public static Map<String, List<String>> groupByValue(final Map<String, String> input, final Set<String> take) {
    return input.entrySet().stream()
            .filter(e -> take.contains(e.getKey()))
            .collect(groupingBy(Entry::getValue, mapping(Entry::getKey, toList())));
}

和跑步:

代码语言:javascript
复制
groupByValue(example, Set.of("1", "3")).forEach((k, v) -> System.out.printf("%s->%s%n", k, v));

给予:

代码语言:javascript
复制
A->[1, 3]

NB: --我使用的是Set,而不是ListSet保证其contains方法将在O(1)中运行,而对于List则在O(n)中运行。因此,List将是,非常低效的。根据输入的大小,在过滤之前将List复制到Set中可能会更好:

代码语言:javascript
复制
private Map<File, List<File>> getAllFiles(List<File> files) {
    final Set<File> filter = Set.copyOf(files);
    return AppStorage.getInstance().getApplicationBean().getInputFilesWithTskFile()
            .entrySet()
            .stream()
            .filter(e -> filter.contains(e.getKey()))
            .collect(groupingBy(Entry::getValue, mapping(Entry::getKey, toList())));
}
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49695144

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档