如何使用 lambda 表达式计算按钮点击次数?
How to count button clicks with lambda expression?
在这部分代码中,我想计算用户按下按钮的次数。问题是,如果我声明数字来计算函数外的点击次数,它根本不会发生。这就是我的意思:
byte numButtonClicks = 0;
tellingIntroButton.addActionListener(e -> {
numButtonClicks ++;
System.out.println(numButtonClicks);
});
并且在内部声明它也不是一个选项,因为它总是会被重置。
感谢您的帮助!
能否请您告诉我您的确切错误是什么?getting.IfnumButtonClicks 是一个局部变量,您不能在 lambda 函数内对捕获的局部变量进行变异。使它成为一个 LongAdder class 变量,它是原子的并且为并发而设计。
LongAdder numButtonClicks= new LongAdder();
tellingIntroButton.addActionListener(e -> {
numButtonClicks.increment();
System.out.println(numButtonClicks);
});
如果你有类似的东西
public class YourComponent extends JFrame { // or whatever it is you're extending
// ....
public void init() {
// ...
byte numButtonClicks = 0;
tellingIntroButton.addActionListener(e -> {
numButtonClicks ++;
System.out.println(numButtonClicks);
});
}
// ...
}
您会 运行 遇到一些问题。
在匿名内部 class(例如您的动作侦听器)中使用的变量必须是隐式最终的。您在另一个答案的评论中提到的例外,
Exception in thread "main" java.lang.Error: Unresolved compilation problem: Local variable numButtonClicks defined in an enclosing scope must be final or effectively final
告诉你你的计数器变量不是最终的
您正在使用 byte
字段作为计数器。为什么不是 int
或 long
?
您不能在方法中声明最终的 int
或 long
并递增它。
您可以通过在您的 class 上添加成员来解决此问题,例如
public class YourComponent extends JFrame { // or whatever it is you're extending
// ....
private int numButtonClicks = 0;
public void init() {
// ...
tellingIntroButton.addActionListener(e -> {
YourComponent.this.numButtonClicks++;
System.out.println(numButtonClicks);
});
}
// ...
}
或者,有点像其他答案所建议的那样,如果并发在这里对您来说是个问题(如果计数可以由不同的线程修改),您可以使用 java8 对象,例如 LongAdder
.如果你走这条路 (LongAdder
) 如果你在一个方法的范围内声明它,它需要被声明为 final。
在这部分代码中,我想计算用户按下按钮的次数。问题是,如果我声明数字来计算函数外的点击次数,它根本不会发生。这就是我的意思:
byte numButtonClicks = 0;
tellingIntroButton.addActionListener(e -> {
numButtonClicks ++;
System.out.println(numButtonClicks);
});
并且在内部声明它也不是一个选项,因为它总是会被重置。 感谢您的帮助!
能否请您告诉我您的确切错误是什么?getting.IfnumButtonClicks 是一个局部变量,您不能在 lambda 函数内对捕获的局部变量进行变异。使它成为一个 LongAdder class 变量,它是原子的并且为并发而设计。
LongAdder numButtonClicks= new LongAdder();
tellingIntroButton.addActionListener(e -> {
numButtonClicks.increment();
System.out.println(numButtonClicks);
});
如果你有类似的东西
public class YourComponent extends JFrame { // or whatever it is you're extending
// ....
public void init() {
// ...
byte numButtonClicks = 0;
tellingIntroButton.addActionListener(e -> {
numButtonClicks ++;
System.out.println(numButtonClicks);
});
}
// ...
}
您会 运行 遇到一些问题。
在匿名内部 class(例如您的动作侦听器)中使用的变量必须是隐式最终的。您在另一个答案的评论中提到的例外,
Exception in thread "main" java.lang.Error: Unresolved compilation problem: Local variable numButtonClicks defined in an enclosing scope must be final or effectively final
告诉你你的计数器变量不是最终的
您正在使用
byte
字段作为计数器。为什么不是int
或long
?您不能在方法中声明最终的
int
或long
并递增它。
您可以通过在您的 class 上添加成员来解决此问题,例如
public class YourComponent extends JFrame { // or whatever it is you're extending
// ....
private int numButtonClicks = 0;
public void init() {
// ...
tellingIntroButton.addActionListener(e -> {
YourComponent.this.numButtonClicks++;
System.out.println(numButtonClicks);
});
}
// ...
}
或者,有点像其他答案所建议的那样,如果并发在这里对您来说是个问题(如果计数可以由不同的线程修改),您可以使用 java8 对象,例如 LongAdder
.如果你走这条路 (LongAdder
) 如果你在一个方法的范围内声明它,它需要被声明为 final。