2016-03-05 27 views
1

我需要更改中的lambda事件处理程序内的局部变量。在java中编辑局部变量lambda

SerialPort comPorts[] = SerialPort.getCommPorts(); 
MenuItem[] portsItems = new MenuItem[10]; 
int q=0; 
    for (SerialPort port : comPorts) { 
     portsItems[q] = new MenuItem(port.getSystemPortName()); 
     portsItems[q].setOnAction(actionEvent -> { 
       portNum = q; 
       connect.setDisable(false); 
     }); 
     comPortsMenu.getItems().add(portsItems[q]); 
    } 

的问题是我需要在每个循环递增Q,但我不能这样做,因为q必须最终有效最终将拉姆达内部使用。

+0

@AndrewTobilko你引用了他的确切单词。 –

+0

使'q'成为类实例字段。 –

+2

你在哪里试图增加值?如果你只需要“在循环中”,你可以在lambda表达式中做到这一点。如果你需要一个具有q值的最终变量,只需复制它:'final int pNumber = q;'然后'portNum = pNumber;'将起作用。 –

回答

2

我认为你正在寻找类似

for (SerialPort port : comPorts) { 
    portsItems[q] = new MenuItem(port.getSystemPortName()); 
    int portNumber = q ; // effectively final 
    portsItems[q].setOnAction(actionEvent -> { 
     portNum = portNumber; 
     connect.setDisable(false); 
    }); 
    comPortsMenu.getItems().add(portsItems[q]); 

    // increment: 
    q++ ; 
} 
+0

我想他想改变lambda体内的变量,否则他没有编译错误。 – Andrew

+0

@AndrewTobilko不正确。 'q ++'写入'q'因此'q'不是最终的。 @James_D你可以使这个变量成为'final'。在这里保持有效决定是毫无意义的。 – fabian

+0

它工作感谢男人:) 可以解释我如何解决它,为什么我们必须在lambda中使用final? –

0

你可以做一个整数的选项卡,并使用第一个索引来增加。 在lambda变量被捕获,所以引用必须是最终的。 所以引用不能被另一个替代。这是因为我们可以使用一个int值对象的数组。

+0

你做吧? –

+0

int [] value = new int [1]; value [0] –

0

如果你是开放的使用Apache的百科全书,类易变*家庭提供价值的封友好“拳击”一个好的机制,因为框架提供的大写字母框没有。

对于上面的情况,将q替换为MutableInt是可行的。

这就是说,通过使用这个特殊的例子,你可以通过使用portsItems的(可变长度)列表和相应的'port'值的add()和size() - 1组合来获得更好的结果。