Java 如何使用lambdas正确地创建多级映射?

Java 如何使用lambdas正确地创建多级映射?,java,lambda,java-stream,collectors,Java,Lambda,Java Stream,Collectors,我正在使用JCIFS比较文件夹acceptor和sender中的文件。在比较过程中,可能出现两种情况: -接受程序中不存在文件 -文件存在于接受程序中 我需要得到一个地图,其中比较的文件是由上述两种类型分组,所以我可以复制不存在的文件或检查现有文件的大小和修改日期 我想使用lambdas和streams来实现它,因为在不久的将来我不会使用并行流,而且它也很方便\ 我已成功创建了一个工作原型方法,用于检查文件是否存在并创建映射: private Map<String, Boolean

我正在使用JCIFS比较文件夹acceptor和sender中的文件。在比较过程中,可能出现两种情况: -接受程序中不存在文件 -文件存在于接受程序中

我需要得到一个地图,其中比较的文件是由上述两种类型分组,所以我可以复制不存在的文件或检查现有文件的大小和修改日期

我想使用lambdas和streams来实现它,因为在不久的将来我不会使用并行流,而且它也很方便\

我已成功创建了一个工作原型方法,用于检查文件是否存在并创建映射:

    private Map<String, Boolean> compareFiles(String[] acceptor, String[] sender) {

        return Arrays.stream(sender)
                .map(s -> new AbstractMap.SimpleEntry<>(s, Stream.of(acceptor).anyMatch(s::equals)))
Map.Entry::getValue)));
                .collect(collectingAndThen(
                        toMap(Map.Entry::getKey, Map.Entry::getValue),
                        Collections::<String,Boolean> unmodifiableMap));
    }
但我不能添加更高级别的地图值分组

我有这样一段不起作用的代码:

    private Map<String, Boolean> compareFiles(String[] acceptor, String[] sender) {

        return Arrays.stream(sender)
                .map(s -> new AbstractMap.SimpleEntry<>(s, Stream.of(acceptor).anyMatch(s::equals)))
                .collect(groupingBy(
                        Map.Entry::getValue,
                        groupingBy(Map.Entry::getKey, Map.Entry::getValue)));
    }
}
我的代码无法编译,因为我错过了一些非常重要的东西。。有人能帮我解释一下怎么把这个lambda弄好吗

方法参数中的p.S.数组是SMB文件samba目录:

private final String master = "smb://192.168.1.118/mastershare/";
private final String node = "smb://192.168.1.118/nodeshare/";

SmbFile masterDir   = new SmbFile(master);
SmbFile nodeDir     = new SmbFile(node);

Map<Boolean, <Map<String, Boolean>>> resultingMap = compareFiles(masterDir, nodeDir);

我已经设法解决了我的问题。我的类型不匹配,因此工作代码为:

private Map<Boolean, Map<String, Boolean>> compareFiles(String[] acceptor, String[] sender) {

        return Arrays.stream(sender)
                .map(s -> new AbstractMap.SimpleEntry<>(s, Stream.of(acceptor).anyMatch(s::equals)))
                .collect(collectingAndThen(
                        groupingBy(Map.Entry::getValue, toMap(Map.Entry::getKey, Map.Entry::getValue)),
                        Collections::<Boolean, Map<String, Boolean>> unmodifiableMap));
    }

我已经设法解决了我的问题。我的类型不匹配,因此工作代码为:

private Map<Boolean, Map<String, Boolean>> compareFiles(String[] acceptor, String[] sender) {

        return Arrays.stream(sender)
                .map(s -> new AbstractMap.SimpleEntry<>(s, Stream.of(acceptor).anyMatch(s::equals)))
                .collect(collectingAndThen(
                        groupingBy(Map.Entry::getValue, toMap(Map.Entry::getKey, Map.Entry::getValue)),
                        Collections::<Boolean, Map<String, Boolean>> unmodifiableMap));
    }

收集到具有相同值的嵌套映射中不是很有用。生成的贴图只能有两个键,true和false。当您对其调用gettrue时,您将得到一个映射,其中所有字符串键都冗余映射为true。同样,getfalse将为您提供一个所有值都为false的映射

对我来说,看起来你真的想要

private Map<Boolean, Set<String>> compareFiles(String[] acceptor, String[] sender) {
    return Arrays.stream(sender)
        .collect(partitioningBy(Arrays.asList(acceptor)::contains, toSet()));
}

同样,新HashSetArrays.asListacceptor的准备工作只做了一次,而对发送方的每个元素进行的contains调用将不再依赖于acceptor的大小。

收集到具有相同值的嵌套映射中,不是很有用。生成的贴图只能有两个键,true和false。当您对其调用gettrue时,您将得到一个映射,其中所有字符串键都冗余映射为true。同样,getfalse将为您提供一个所有值都为false的映射

对我来说,看起来你真的想要

private Map<Boolean, Set<String>> compareFiles(String[] acceptor, String[] sender) {
    return Arrays.stream(sender)
        .collect(partitioningBy(Arrays.asList(acceptor)::contains, toSet()));
}
同样,新HashSetArrays.asListacceptor的准备工作只完成一次,而对发送方的每个元素执行的contains调用将不再依赖于acceptor的大小