Java8 Lambda forEach如何存值到全局变量?类型不匹配问题求助
解决Java8 Lambda forEach赋值全局变量的类型不匹配问题
嘿,我来帮你搞定这个问题!首先得说清楚你为啥会遇到这个错误:forEach方法的返回值是void,它只是用来遍历集合并对每个元素执行操作,根本没法返回任何值,所以你直接把它赋值给Long类型的product_id肯定会报类型不匹配的错误。
你原来的循环逻辑是把列表中最后一个Product的id赋值给product_id,要在Java8里实现同样的逻辑,得用Stream API的reduce或者其他方法,而不是forEach。下面是对应的正确写法:
// 获取列表最后一个元素的id,列表为空时返回null(可根据需求修改默认值) Long product_id = listProducts.stream() .reduce((previousProduct, currentProduct) -> currentProduct) // 遍历过程中保留最后一个元素 .map(Product::getId) // 将Product对象转换为它的id值 .orElse(null); // 当列表为空时的默认返回值
代码细节解释:
reduce((a, b) -> b):这个操作会遍历整个Stream,每次都用后面的元素覆盖前面的,最终得到列表的最后一个元素,返回的是Optional<Product>(避免空指针风险)。map(Product::getId):把Optional<Product>转换成Optional<Long>,也就是提取出Product的id值。orElse(null):如果列表为空,reduce会返回空的Optional,这时候就会返回null;你也可以改成orElse(0L)之类的默认值,完全根据业务需求调整。
如果你的业务要求列表不能为空,也可以用orElseThrow()来抛出异常,比如:
Long product_id = listProducts.stream() .reduce((prev, curr) -> curr) .map(Product::getId) .orElseThrow(() -> new IllegalArgumentException("Product列表不能为空"));
另外,如果你非要用forEach来实现(虽然没必要,不如上面的写法优雅),可以先初始化product_id,然后在forEach里赋值:
Long product_id = null; listProducts.forEach(product -> { product_id = product.getId(); // 注意:如果是局部变量需要声明为final或者有效final,全局变量则无此限制 });
不过这种写法不如Stream的方式清晰,而且不符合Java8函数式编程的风格,还是更推荐前面的Stream实现方案。
内容的提问来源于stack exchange,提问作者Karthikeyan
相关产品推荐
相关产品推荐

