添加到 ArrayList 时如何避免“lambda 表达式中的参数类型不兼容”?

m0m*_*eni 6 java lambda arraylist java-8 java-stream

我有以下代码

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;
}
Run Code Online (Sandbox Code Playgroud)

forEach引发错误

Error:(20, 16) java: incompatible types: incompatible parameter types in lambda expression
Run Code Online (Sandbox Code Playgroud)

如何修复/避免此错误?我不太确定如何在这里应用解释问题的答案:Lambda Expression and generic method

编辑:

鉴于答案,更正是将 forEach 中的 lambda 替换为

.forEach((entry) -> myList.add(entry.getKey()));
Run Code Online (Sandbox Code Playgroud)

SLa*_*aks 6

entrySet()返回一组Pair<K, V>.

forEach()的 lambda 因此采用该类型的单个参数;不是两个整数参数。


Mis*_*sha 5

您正在以 java7-ish 的方式进行处理。从内部修改外部数据结构forEach并不是 Streams API 的使用方式。Streams API 文档在包摘要的“副作用”部分特别警告不要进行此类使用java.util.stream

不要从内部附加到列表或映射forEach,而是使用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());
}
Run Code Online (Sandbox Code Playgroud)

  • 啊,好吧,那太酷了。我大约有 2 年没有写过 Java,这就是为什么它目前是混合的。在流中不产生副作用是有道理的,但我不太确定我在做什么。 (2认同)