简体   繁体   中英

How to find the sum of values of map whose key contains the given prefix?

I have a method with the following signature:

int sum(Map<String, Integer> map, String target) { }

I am trying to find the sum of values of the entries who key has the prefix as the given target string. I want to do this using streams. This is what I've done:

return map.entrySet().stream()
    .filter((k, v) -> k.startsWith(target))
    .map((k, v) -> v)
    .sum();

Compiler gives the following error:

error: incompatible types: incompatible parameter types in lambda expression

What am I doing wrong here?

The problem is that entrySet() is a collection of Entry<> , there is no separate k and v . You should try something like this:

return map.entrySet().stream()
    .filter((entry) -> entry.getKey().equals(target))
    .mapToInt((entry) -> entry.getValue())
    .sum();

Or for your edited version with startsWith :

return map.entrySet().stream()
    .filter((entry) -> entry.getKey().startsWith(target))
    .mapToInt((entry) -> entry.getValue())
    .sum();

Map's entrySet returns a Set<Map.Entry<K, V>> .

Use Entry's getKey and getValue to access the key and value and use mapToInt and sum .

map.entrySet().stream()
        .filter(entry -> entry.getKey().startsWith(target))
        .mapToInt(Map.Entry::getValue)
        .sum();

map.entrySet().stream() gives you a stream of Map.Entry<K, V> elements.

You should use e -> e.getKey().startsWith(target) to get the entries who's key has the prefix as the value "target"

Map.Entry::getValue gives you the values of the filtered entries so you can sum the values.

Try this:

return map.entrySet().stream()
    .filter(e -> e.getKey().startsWith(target))
    .map(Map.Entry::getValue)
    .reduce(0, Integer::sum);

A Map.Entry is a single object that cannot be accessed by (k, v) ->... . You can get that entry's key and value using its corresponding methods getKey() and getValue() or use a method reference and collect the sum of the values:

int sum(Map<String, Integer> map, String target) {
    return map.entrySet().stream()
            .filter(e -> e.getKey().startsWith(target))
            // use a lamda expression and call the method
            .collect(Collectors.summingInt(e -> e.getValue()));
}

or with a method reference

int sum(Map<String, Integer> map, String target) {
    return map.entrySet().stream()
            .filter(e -> e.getKey().startsWith(target))
            // use method reference
            .collect(Collectors.summingInt(Map.Entry::getValue));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM