How to avoid "incompatible parameter types in lambda expression" when adding to an ArrayList?

16,535

Solution 1

You are going about it in a java7-ish way. Modifying external data structures from inside forEach is not how Streams API was meant to be used. Streams API documentation specifically warns against such use in the Side-Effects section of java.util.stream package summary

Instead of appending to list or map from inside forEach, use collect:

import static java.util.Comparator.reverseOrder;
import static java.util.Map.Entry.comparingByValue;
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;


public static List<Integer> topKFrequent(int[] nums, int k) {
    Map<Integer, Long> freq = Arrays.stream(nums).boxed()
            .collect(groupingBy(x->x, counting()));

    return freq.entrySet()
            .stream()
            .sorted(comparingByValue(reverseOrder()))
            .limit(k)
            .map(Map.Entry::getKey)
            .collect(toList());
}

Solution 2

entrySet() returns a set of Pair<K, V>.

forEach()'s lambda therefore takes a single parameter of that type; not two integer parameters.

Share:
16,535
m0meni
Author by

m0meni

On a scale of one to my account, this is my account.

Updated on August 08, 2022

Comments

  • m0meni
    m0meni over 1 year

    I have the following code

    public static List<Integer> topKFrequent(int[] nums, int k) {
      List<Integer> myList = new ArrayList<>();
      HashMap<Integer, Integer> map = new HashMap<>();
    
      for (int n : nums) {
        if (!map.containsKey(n)) map.put(n, 1);
        else map.put(n, map.get(n) + 1);
      }
    
      map.entrySet().stream()
        .sorted(Map.Entry.<Integer, Integer>comparingByValue().reversed())
        .limit(k)
        .forEach((key, value) -> myList.add(key));
    
      return myList;
    }
    

    The forEach throws the error

    Error:(20, 16) java: incompatible types: incompatible parameter types in lambda expression
    

    How can I fix/avoid this error? I'm not quite sure how to apply the answer here that explains the problem: Lambda Expression and generic method

    Edit:

    Given the answer, the correction is to replace the lambda inside the forEach with

    .forEach((entry) -> myList.add(entry.getKey()));
    
  • m0meni
    m0meni almost 8 years
    Ah ok that's very cool. I haven't written Java in about 2 years, which is why it's currently a mix. It makes sense to not have side effects in streams, but I wasn't quite sure what I was doing yet.