【问题标题】:How to avoid "incompatible parameter types in lambda expression" when adding to an ArrayList?添加到 ArrayList 时如何避免“lambda 表达式中的参数类型不兼容”?
【发布时间】:2016-05-09 22:07:25
【问题描述】:

我有以下代码

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;
}

forEach 抛出错误

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

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

编辑:

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

.forEach((entry) -> myList.add(entry.getKey()));

【问题讨论】:

  • 遗憾的是 Java 不允许元组解包。
  • P.S.问题标题很糟糕——答案肯定是“不要提供不兼容的参数”。
  • @Boris the Spider:但是编写一个将BiConsumer&lt;K,V&gt; 转换为Consumer&lt;Map.Entry&lt;K,V&gt;&gt; 的实用方法是微不足道的……
  • @Boris the Spider:更糟糕的是,Java 没有元组……
  • @AR7:请注意,对于您的第一个循环,您可以使用已接受答案的流解决方案,但是当您使用循环时,您可以将if (!map.containsKey(n)) map.put(n, 1); else map.put(n, map.get(n) + 1); 替换为map.merge(n, 1, Integer::sum);。所以不仅有 Stream API,Collection API 也有很多有用的新方法。

标签: java arraylist lambda java-8 java-stream


【解决方案1】:

entrySet() 返回一组Pair&lt;K, V&gt;

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

【讨论】:

    【解决方案2】:

    您将以 java7-ish 的方式进行操作。从 forEach 内部修改外部数据结构并不是 Streams API 的用途。 Streams API 文档在 java.util.stream package summary 的 Side-Effects 部分特别警告不要使用这种方法

    不要从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());
    }
    

    【讨论】:

    • 啊,这很酷。我已经有大约 2 年没有编写 Java 了,这就是为什么它目前是混合的。在流中没有副作用是有道理的,但我不太确定我在做什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    • 2021-10-13
    • 2020-07-26
    • 2023-04-05
    相关资源
    最近更新 更多