首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >变量已在方法lambda中定义。

变量已在方法lambda中定义。
EN

Stack Overflow用户
提问于 2014-03-31 13:56:52
回答 5查看 22.1K关注 0票数 19

考虑以下几乎可编译的Java 8代码:

代码语言:javascript
运行
AI代码解释
复制
public static void main(String[] args) {

    LinkedList<User> users = null;
    users.add(new User(1, "User1"));
    users.add(new User(2, "User2"));
    users.add(new User(3, "User3"));

    User user = users.stream().filter((user) -> user.getId() == 1).findAny().get();
}

static class User {

    int id;
    String username;

    public User() {
    }

    public User(int id, String username) {
        this.id = id;
        this.username = username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public int getId() {
        return id;
    }
}

您会注意到User user = users.stream().filter((user) -> user.getId() == 1).findAny().get();抛出一个编译器错误:

变量用户已在方法main(String[])中定义

我的问题是:为什么Lambda表达式考虑与已经定义的Lambda表达式在同一行上初始化的变量?我理解Lambda自己寻找(并使用)局部变量,因此不能将在Lambda中使用的变量命名为外部变量。但是,为什么被定义的变量被认为已经定义了呢?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-03-31 15:40:26

让我们来看看关于名称及其作用域的Java语言规范

方法(§8.4.1)、构造函数(§8.8.1)或lambda表达式(§15.27)的形式参数的范围是方法、构造函数或lambda表达式的整个主体。 块中局部变量声明的作用域(§14.4)是声明显示为的块的其余部分,从它自己的初始化器开始,并在局部变量声明语句中包含右边的任何其他声明器。

然后,以遮蔽和遮挡为主题

局部变量(§14.4)、形式参数(§8.4.1、§15.27.1)、异常参数(§14.20)和本地类(§14.3)只能使用简单的名称,而不是限定的名称(§6.2)。 某些声明在局部变量、形式参数、异常参数或本地类声明的范围内是不允许的,因为仅使用简单的名称就不可能区分声明的实体。 如果使用局部变量v的名称来声明v范围内的新变量,则为编译时错误,除非新变量是在声明在v.范围内的类中声明的。

所以,在

代码语言:javascript
运行
AI代码解释
复制
User user = users.stream().filter((user) -> user.getId() == 1).findAny().get();

变量user的作用域是该块中它之后的所有内容。现在,您正在尝试使用该变量的名称在作用域中声明一个新变量,但不使用

声明在v.范围内的类中的

因此会出现编译时错误。(它是在lambda表达式中声明的,而不是在类中声明的)

票数 17
EN

Stack Overflow用户

发布于 2014-03-31 14:00:51

看看代码

代码语言:javascript
运行
AI代码解释
复制
User user = users.stream().filter((user) -> user.getId() == 1).findAny().get();

变量名为user,lambda中的变量也是user

试着把它改变成这样

代码语言:javascript
运行
AI代码解释
复制
User user = users.stream().filter((otherUser) -> otherUser.getId() == 1).findAny().get();
票数 8
EN

Stack Overflow用户

发布于 2017-11-09 07:12:04

注意,这个限制将在以后的版本中被删除。来自九月-302号的报价

Lambda参数不允许在封闭作用域中隐藏变量。(换句话说,lambda的行为类似于for语句-参见JLS),这通常会导致问题,如下(非常常见)所示:

代码语言:javascript
运行
AI代码解释
复制
Map<String, Integer> msi = ...
...
String key = computeSomeKey();
msi.computeIfAbsent(key, key -> key.length()) //error

在这里,在computeIfAbsent调用中将名称键重用为lambda参数的尝试失败了,因为在封闭上下文中已经定义了同名变量。 最好取消这个限制,允许lambda参数(和用lambda声明的局部变量)隐藏在包围作用域中定义的变量。(反对的一个可能的论点是可读性:如果允许lambda参数阴影,那么在上面的示例中,标识符'key‘意味着在使用它的两个地方有两个不同的东西,并且似乎没有语法障碍来分隔这两个用法。)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22773003

复制
相关文章
爬虫--xpath匹配,requests库
使用xpath得到老师的图片链接和简介信息,并且把图片保存下来,老师简介保存到文本中; 要求: 杨老师的信息图片<img src="pics/ygf.jpg"> 图片保存的名字叫ygf.jpg,其他老师类似;并且都保存到当前目录下的image目录 杨老师的信息保存文件名叫“ygf.txt”,其他老师类似;并且保存到当前目录下的text目录 代码: import requests from lxml import etree import os def save(img_url, desc):
用户2337871
2019/07/19
5100
爬虫--xpath匹配,requests库
scala 模式匹配的几个模式
Scala 的模式匹配是类似与正则匹配的的模式匹配,但是不仅仅如此,它还可以匹配对象的内在的构建形式.
Tim在路上
2020/08/04
1.2K0
模式匹配
如果在不设置全文搜索的情况下,如何过滤查询结果,您会选择哪种方法?LIKE也许是最容易想到的:
yzsDBA
2021/02/03
9990
模式匹配
匹配操作符(绑定操作符): =~、!~ =~检验匹配是否成功:result= var =~ /abc/;若在该字符串中找到了该模式,则返回非零值,即true,不匹配则返回false。
生信补给站
2020/08/06
1.7K0
Scala 的模式匹配
最近开始学习 Scala,相较于学习 Haskell 的过程来看,Scala 真是直观得多,友好得多,更容易上手。以前写过关于从熟悉的 Java 和 JavaScript 来逐步学习 Groovy 和 Haskell 的文章,这以后再来学习 Scala 的话,就可以不断比较了。如果和我一样有 Java 经验的话但是从来没有接触过 Scala 的话,建议先阅读这篇文章,A Scala Tutorial for Java Programmers,一边比较,一边熟悉,同时配套的还有这个,Scala for Java programmers – Joakim Ohlrogge & Enno Runne,Youtube 上的视频,很直观,然后再从 Scala 官网的文档上面逐步涉入。
四火
2022/07/19
1K0
Scala 的模式匹配
Rust模式匹配
模式匹配是从函数式编程语言(例如:Haskell,Lisp)吸收而来的,用于为复杂的类型系统提供一个轻松的解构能力。rust使用match来提供模式匹配的功能。mathc类似于其它编程语言中的switch-case,但是远比switch-case强大。match的通用模式如下所示。
zy010101
2023/02/27
1.5K0
有趣的Scala模式匹配
它被称为模式匹配,模式匹配包含了一系列以case关键字开头的分支,每一个分支包含一个模式或者是多个表达式。模式有很多种,例如常量模式('*',1),变量模式(可以匹配任何值),通配模式(又见面了,'_'符号),构造方法模式(类似于样例类的初始化)等等。 用一个例子简单说明就是:
哒呵呵
2018/08/06
1.1K0
Rust中的模式匹配
在其它一些语言中,let x = 5 之类的语句,仅仅只是赋值语句。但是在rust中,可以换个角度理解,认为5这个值匹配到了x变量。如果觉得有些牵强,可以再来一个示例:
菩提树下的杨过
2021/11/30
1.9K0
Rust中的模式匹配
Swift中的模式匹配
Swift 作为一门现代语言,除去安全,快速等特性之外,还有个明显有别于其他语言的特性,就是巨量细致入微的语言特性。类似iOS API,初学者觉得繁杂,无从下手,但是熟悉之后,绝对能少写不少代码。
小刀c
2022/09/21
1.8K0
Scala 模式匹配
一个模式匹配包含了一系列备选项,每个都开始于关键字 case。每个备选项都包含了一个模式及一到多个表达式。箭头符号 => 隔开了模式和表达式。
王知无-import_bigdata
2019/03/19
8980
《模式识别与智能计算》基于PCA的模板匹配法
算法流程: 选取各类全体样本组成矩阵X,待测样品 计算协方差矩阵S 根据S的特征值选取适合的矩阵C 使用矩阵C降维 采用模板匹配开始多类别分类 算法实现 PCA降维算法 def pca(x,k=0,percent = 0.9): """ :function: 主成分分析法 :param X: 数据X m*n维 n表示特征个数,m表示数据个数 :param K: K表是要保留的维度 :param percent: 样本所占比例 :return: 返回特征向量
Max超
2020/01/16
7510
less中的匹配模式
首先来看如下的代码,一个 div 元素,分别设置了上下左右的宽度高度和颜色,然后在浏览器中打开发现四个不同的角都是一个小小的三角形如下
程序员 NEO
2023/09/29
2450
less中的匹配模式
朴素的模式匹配算法
子串(又称模式串)的定位操作通常称做串的模式匹配,是串中最重要的操作之一。朴素的匹配方法(BRUTE FORCE 算法,BF 算法)逻辑思路:
用户7737280
2021/11/10
1K0
Lua模式匹配
Lua并不使用POSIX规范的正则表达式[4](也写作regexp)来进行模式匹配。主要的原因出于程序大小方面的考虑:实现一个典型的符合POSIX标准的regexp大概需要4000行代码,这比整个Lua标准库加在一起都大。
sunsky
2020/08/20
1.8K0
模式匹配算法
模式匹配算法: 定义一个主串字符串S="goodgoogle",再定义一个模式串字符串T="google",然后依次遍历主串中的字符,判断,模式串是否在主串中存在,这种模式串的定位操作通常称为串的模式匹配 代码: 1 /** 2 * 朴素的模式匹配算法 3 * @author wydream 4 * 5 */ 6 7 public class OrdinaryModel { 8 9 public static void main(String[] args)
说故事的五公子
2019/09/11
9320
基于OpenCV的直方图匹配
如何为图像生成直方图,如何使直方图相等,最后如何将图像直方图修改为与其他直方图相似。
AI算法与图像处理
2020/12/07
1.4K0
Python的模式匹配库pampy
模式匹配即给定某种模式,用这种模式去检查序列或字符串是否符合这种模式,这种技术在自然语言处理中经常使用。
Python研究所
2022/06/17
6810
4.3 串的模式匹配算法
1、子串的定位操作通常称做串的模式匹配(其中T称为模式串),是各种串处理系统中最重要的操作之一。
小林C语言
2019/07/12
7240
Python匹配方式之xpath,还在用正则吗?一节课带你学会更简单的xpath
  XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 都构建于 XPath 表达之上。
云飞
2018/09/14
7370
点击加载更多

相似问题

基于节点()包含()内容的Xpath匹配

14

基于属性引用的XPath节点匹配

37

基于匿名的模式匹配

10

基于OR逻辑的模式匹配

20

基于列表长度的匹配模式匹配

24
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档