Orland
Orland

Reputation: 13

Using ComputeIfAbsent & ComputeIfPresent to put list into map

I have a blok of code that's work well for me :

for (String word : distinctWordsInOneLigne) {
                        Map<String, List<Integer>> map = new HashMap<>();
                        if (!word.isEmpty()) {
                            List<Integer> linePositionsOfWord = new LinkedList<>();
                            if (currentLine.contains(word)) {
                                linePositionsOfWord.add(numLine);
                                if (mapAllWordsPositionInFilesInFolder.containsKey(word)) {
                                    Map<String, List<Integer>> mapList = mapAllWordsPositionInFilesInFolder.get(word);
                                    if (mapList.containsKey(filePath)) {
                                        List<Integer> list = mapList.get(filePath);
                                        list.add(numLine);
                                    } else {
                                        mapList.put(filePath, linePositionsOfWord);
                                    }
                                } else {
                                    map.put(filePath, linePositionsOfWord);
                                    mapAllWordsPositionInFilesInFolder.put(word, map);
                                }
                            }
                        }
                    }

NB: Map<String, Map<String, List<Integer>>> mapAllWordsPositionInFilesInFolder = new HashMap<>(); The result of i somethinglike this :

{word1={file2.txt=[7], file1.txt=[1, 2]}, word2={file2.txt=[1, 2, 9, 13], file5.txt=[2, 3, 9]}}

Now i want have some result but now by using ComputeIfAbsent & ComputeIfPresent instead of containsKey and all this if ... else.

I tried this but not work :

mapAllWordsPositionInFilesInFolder.computeIfAbsent(word,v -> new HashMap<>())
                                        .computeIfAbsent(filePath,  val -> linePositionsOfWord);

mapAllWordsPositionInFilesInFolder.computeIfPresent(word,(k,v)->{
                                    v.computeIfPresent(filePath, (x, y) -> linePositionsOfWord.add(numLine));
                                    return v;
                                });

I need help please ! thank's :)

Upvotes: 0

Views: 1802

Answers (1)

Andreas
Andreas

Reputation: 159135

You wouldn't use computeIfPresent() for this, but you would use computeIfAbsent() like this:

for (String word : distinctWordsInOneLigne) {
    if (! word.isEmpty() && currentLine.contains(word)) {
        mapAllWordsPositionInFilesInFolder.computeIfAbsent(word, k -> new HashMap<>())
                                          .computeIfAbsent(filePath, k -> new LinkedList<>())
                                          .add(numLine);
    }
}

The original code was very badly written. Even without using computeIfPresent(), it can be cleaned up a lot, eliminating repeated code. This is how it should have been written:

for (String word : distinctWordsInOneLigne) {
    if (! word.isEmpty() && currentLine.contains(word)) {
        Map<String, List<Integer>> mapList = mapAllWordsPositionInFilesInFolder.get(word);
        if (mapList == null) {
            mapList = new HashMap<>();
            mapAllWordsPositionInFilesInFolder.put(word, mapList);
        }
        List<Integer> linePositionsOfWord = mapList.get(filePath);
        if (linePositionsOfWord == null) {
            linePositionsOfWord = new LinkedList<>();
            mapList.put(filePath, linePositionsOfWord);
        }
        linePositionsOfWord.add(numLine);
    }
}

With inlining, that can be reduced to:

for (String word : distinctWordsInOneLigne) {
    if (! word.isEmpty() && currentLine.contains(word)) {
        Map<String, List<Integer>> mapList = mapAllWordsPositionInFilesInFolder.get(word);
        if (mapList == null)
            mapAllWordsPositionInFilesInFolder.put(word, mapList = new HashMap<>());
        List<Integer> linePositionsOfWord = mapList.get(filePath);
        if (linePositionsOfWord == null)
            mapList.put(filePath, linePositionsOfWord = new LinkedList<>());
        linePositionsOfWord.add(numLine);
    }
}

Upvotes: 2

Related Questions