どのように私は適切にラムダを使用してマルチレベルのマップを作ることができますか?

Bjiapkl3:

私はJCIFSを使用して、フォルダ内のファイル(アクセプタ&送信者)を比較しています。comparation中に2つの状況が発生する可能性があります - ファイルがないアクセプターに存在する - ファイルがアクセプターに存在します

私は、私は、既存の非既存のファイルまたはchechサイズと変更日付をコピーすることができるように比較ファイルは、言及した二つのタイプによってgrouppedされているマップを、取得する必要があります...

私は近い将来に並列ストリームを使用woultので、私は、それはラムダとストリームを使って作りたい、それもとても便利です... \

私がチェックし、ファイルが存在するかどうかという作業プロトタイプの方法を作るために管理し、マップを作成しました:

    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)));
    }
}

私は非常に重要な何かを逃したので、私のコードは、コンパイルすることはできません...誰も私を助けてくださいとexlainがどのようにこのラムダが正しいにするだろうか?

メソッドのパラメータからPSアレイですSmbFilesサンバディレクトリ:

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);
ホルガー:

同じ値を持つネストされたマップに集め、非常に有用ではありません。結果として生じるがMap<Boolean, Map<String, Boolean>>唯一の2つのキーを持ち、できるtruefalseあなたが呼び出すとget(true)、その上に、あなたが買ってあげるMap<String, Boolean>、すべての文字列キーが重複にマッピングところtrue同様に、get(false)すべての値がどこにあるか、マップ与えるだろうfalse

あなたが実際にしたいように私には、それが見えます

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

どこget(true)あなたの述語がに評価された全ての文字列の集合与えtrue、またはその逆を。

partitioningBy最適化されたバージョンであるgroupingByためbooleanのキー。

Stream.of(acceptor).anyMatch(s::equals)ストリーム機能の乱用です。Arrays(acceptor).contains(s)述語などに使用されたときに単純されArrays.asList(acceptor)::contains、式がArrays.asList(acceptor)一度だけ評価されますと、関数呼び出しcontainsの各評価には、コレクタに渡されます。

ときにacceptor大きくなる、あなたは並列処理を検討したが、ハッシュ・ルックアップと線形探索を置き換えるべきではありません

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

ここでも、の準備作業new HashSet<>(Arrays.asList(acceptor))のみのに対し、一度に行われるcontainsのすべての要素のために行わ呼び出しは、sender、の大きさに依存しませんacceptorもう。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=337363&siteId=1