java:是否可以为Buttons数组设置lambda表达式是for循环? 如果是这样的话?

我希望能够做到这样的事情:

for(i = 0; i  { button[i].setDisable(true) } ); } 

但是,我得到一个错误说"local variables referenced from a lambda expression must be final or effectively final" 。 我怎么还能像上面的代码那样做(如果可能的话)? 如果无法完成,应该做些什么来获得类似的结果呢?

正如错误消息所示,从lambda表达式引用的局部变量必须是最终的或有效的final(“有效最终”意味着编译器可以使它最终为您)。

简单的解决方法:

 for(i = 0; i < 10; i++) { final int ii = i; button[i].setOnAction( ae -> { button[ii].setDisable(true) } ); } 

由于您使用的是lambdas,因此您也可以从Java 8的其他function(如流)中受益。

例如, IntStream

支持顺序和并行聚合操作的一系列原始int值元素。 这是Stream的int原始特化。

可以用来替换for循环:

 IntStream.range(0,10).forEach(i->{...}); 

所以现在你有一个可以用于你的目的的索引:

 IntStream.range(0,10) .forEach(i->button[i].setOnAction(ea->button[i].setDisable(true))); 

您还可以从数组生成流:

  Stream.of(button).forEach(btn->{...}); 

在这种情况下,您将没有索引,因此@shmosel建议您可以使用事件的来源:

 Stream.of(button) .forEach(btn->btn.setOnAction(ea->((Button)ea.getSource()).setDisable(true))); 

编辑

正如@James_D建议的那样,这里不需要向下转发:

 Stream.of(button) .forEach(btn->btn.setOnAction(ea->btn.setDisable(true))); 

在这两种情况下,您还可以从并行操作中受益:

 IntStream.range(0,10).parallel() .forEach(i->button[i].setOnAction(ea->button[i].setDisable(true))); Stream.of(button).parallel() .forEach(btn->btn.setOnAction(ea->btn.setDisable(true))); 

使用Event获取源Node

 for(int i = 0; i < button.length; i++) { button[i].setOnAction(event ->{ ((Button)event.getSource()).setDisable(true); }); } 

Lambda表达式实际上就像一个在流上工作的匿名方法。 为了避免任何不安全的操作,Java已经使得没有可以修改的外部变量可以在lambda表达式中访问。

为了解决它,

final int index = button [i]; 并在lambda表达式中使用index而不是i

你说如果按下按钮,但在你的例子中,列表中的所有按钮都将被禁用。 尝试将侦听器关联到每个按钮,而不是仅禁用它。

对于逻辑,你的意思是这样的:

 Arrays.asList(buttons).forEach( button -> button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { button.setEnabled(false); } })); 

我也喜欢Sedrick的答案,但你必须在循环中添加一个动作监听器。