&引用;变量必须是最终变量;试图使用Java 8 streams API时出现编译器错误
我试图做leetcode——给定一个整数数组,每个元素出现三次,只有一个元素出现一次。我正在尝试使用streams来做这件事,这样我就可以练习Java8了。但我总是会犯不同的错误。我希望使用findFirst(),因为一旦找到元素,就不需要在HashMap上不断迭代&引用;变量必须是最终变量;试图使用Java 8 streams API时出现编译器错误,java,algorithm,java-8,java-stream,Java,Algorithm,Java 8,Java Stream,我试图做leetcode——给定一个整数数组,每个元素出现三次,只有一个元素出现一次。我正在尝试使用streams来做这件事,这样我就可以练习Java8了。但我总是会犯不同的错误。我希望使用findFirst(),因为一旦找到元素,就不需要在HashMap上不断迭代 public class Solution { public int singleNumber(int[] nums) { HashMap<Integer, Integer> map =
public class Solution {
public int singleNumber(int[] nums) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int num: nums){
if (map.containsValue(num))
map.put(num, map.get(num) +1);
else
map.put(num, 1);
}
map.forEach((k, v) -> {
if (v == 1)
return k;
});
}
}
当我尝试
public class Solution {
public int singleNumber(int[] nums) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int num: nums){
if (map.containsValue(num))
map.put(num, map.get(num) +1);
else
map.put(num, 1);
}
Map<Integer, Integer> answer= map.entrySet().stream()
.filter(p -> p.getValue() == 1)
.findFirst()
.collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
return answer.getValue();
}
}
我得到第16行:错误:lambda表达式引用的局部变量必须是final或有效final
预期答案
但若我宣布这个数字是最终的,那个么它会说我不能分配它
当我尝试时(作为流中的最后一行)
.collect(收集器.groupingBy(i->i))
我明白了
第15行:错误:找不到符号:方法收集(收集器>>)
如果我删除流的最后一行并将下一行更改为
.findFirst())
然后我得到
第14行:错误:“;”预计这是两个或三个)
如果我这样做
.findFirst()
然后我得到
第14行:错误:不兼容类型:可选>
无法转换为映射
forEach
不需要返回类型,它是一个“消费”函数,因此会出现错误
在Java中,要回答关于“从lambda表达式引用的局部变量必须是final或有效final”的问题,您不能再次从lambda内部(或实际上在lambda外部)为名为number
的变量赋值。这是Lambda实现方式的一个限制。正如消息所述,必须将其标记为final
,否则在初始化后(实际上是final),您永远不会为number
分配其他值
作为替代解决方案的起点,请尝试使用groupingBy
Map<Integer, List<Integer>> map = Stream.of(1, 1, 1, 2, 3, 3, 3)
.collect(Collectors.groupingBy(i -> i));
编辑
我们可以使用另一个流来返回您想要的单个int
(即2
),而不是使用forEach循环
给定上面的映射输出,您希望过滤并只保留映射中只有一个值的条目,所以接下来执行此操作
List<List<Integer>> onlyOne = map.values().stream()
.filter(v -> v.size() == 1)
.collect(Collectors.toList());
现在,您只需提取值2
免责声明:有很多方法可以解决streams的问题,我试图通过这个示例帮助您从功能上思考,而不是给您一个您可能不理解的单行解决方案“不断得到不同的错误”。。。什么错误?具体点?准确地发布失败的代码,并告诉我们发生了什么错误。在此之前,问题不在主题中。条目上没有collect()方法。您正在迭代和项集(EntrySet)。如果我删除collect(),则我获取可选项无法转换为映射。第14行:错误:不兼容类型:可选项无法转换为映射预期应答您需要开始阅读并理解错误消息。正如javadoc中非常清楚地写的那样,findFirst()返回Optional的一个实例。您正在尝试将此可选项分配给Map类型的变量。可选项不是映射。所以你的代码毫无意义,这就是编译器告诉你的。不要随意尝试。阅读javadoc,并阅读错误消息。您正在尝试随机操作。一旦您了解到
findFirst
返回一个可选
,您应该直接转到可选
的文档,了解如何检查值的存在以及如何提取它。这很容易。没有理由尝试附加一个collect
,它将返回一个Map
,如果这样做有效的话。还有什么是getValue()
?!Map
中没有这样的方法。我将流中的姓氏更改为groupingBy,并得到此错误您的回答行15:错误:找不到符号:方法collect(Collector),我也无法在lambda表达式中声明该数字变量,然后返回该值。我只需要返回一个int,而不是hashmap列表。嗨@Sam看看我的编辑,如果你还有任何问题,请回复
Map<Integer, List<Integer>> map = Stream.of(1, 1, 1, 2, 3, 3, 3)
.collect(Collectors.groupingBy(i -> i));
{1=[1, 1, 1], 2=[2], 3=[3, 3, 3]}
List<List<Integer>> onlyOne = map.values().stream()
.filter(v -> v.size() == 1)
.collect(Collectors.toList());
[[2]]