Search code examples
javajava-stream

Why is map stream sorted after filtering not working?


I have Map<String,Integer> map. I want to filter and sort the map by key and then get 5 percent of their number. I have such a function:

public List<String> getValuableSubStr(){
        List<String> result = new ArrayList<>();
        long size = map.entrySet().stream().filter(e -> e.getKey().length() ==3).count();
        map.entrySet().stream()
                      .filter(e -> e.getKey().length() ==3)
                      .sorted(Map.Entry.<String,Integer>comparingByKey().reversed())
                      .limit((size*5)/100)
                      .peek(e -> result.add(e.getKey()));
        return result;

    }

But after calling the function, I get an empty list, although the map is not empty and forEach are printed normally. What did I do wrong?


Solution

  • peek is not a terminal operation, so it doesn't cause the stream to be evaluated.

    Use forEach instead of peek.

    Or, better, collect directly into a list.

    return map.entrySet().stream()
        .filter(e -> e.getKey().length() ==3)
        .sorted(Map.Entry.<String,Integer>comparingByKey().reversed())
        .limit((size*5)/100)
        .map(Map.Entry::getKey)
        .collect(Collectors.toList());
    

    Actually, since you're dealing only with keys:

    return map.keySet().stream()
        .filter(e -> e.length() ==3)
        .sorted(Comparator.reverseOrder())
        .limit((size*5)/100)
        .collect(Collectors.toList());