在Java中实现递归lambda函数
我不知道下面的事情是否可能。我希望在Java中实现递归lambda函数,java,recursion,lambda,Java,Recursion,Lambda,我不知道下面的事情是否可能。我希望Runnable的run()方法包含Runnable本身,即 reconnects = 3; Runnable executeAfter = () -> { if ( --reconnects < 0 ) { println("%nStop using port %d.", this.port); //... } else { // try to reconnect println("%
Runnable
的run()
方法包含Runnable
本身,即
reconnects = 3;
Runnable executeAfter = () -> {
if ( --reconnects < 0 ) {
println("%nStop using port %d.", this.port);
//...
} else { // try to reconnect
println("%nReconnecting...");
cmdRun = new CmdRun(command, executeAfter);
(new Thread(cmdRun)).start();
//...
}
};
重新连接=3;
Runnable executeAfter=()->{
如果(--重新连接<0){
println(“%n停止使用端口%d.”,此端口);
//...
}否则{//请尝试重新连接
println(“%n正在连接…”);
cmdRun=新的cmdRun(命令,executeAfter);
(新线程(cmdRun)).start();
//...
}
};
这样的事情可能吗?如果是,怎么做?(
CmdRun
的构造函数是CmdRun(String命令,Runnable executeAfter)
)最简单的方法可能是将lambda的内容放在方法中,并使用方法引用定义可运行的。最简单的方法可能是将lambda的内容放在方法中,并使用方法引用定义可运行的。可运行的run()不能包含自引用,因为它是非法的。
我不太确定你想要实现什么,但类似的事情应该会奏效:
class CmdRun implements Runnable {
final Object command;
final Runnable runnable;
final Runnable executeAfter = () -> {
if ( --reconnects < 0 ) {
System.out.println("%nStop using port %d." + port);
//...
} else { // try to reconnect
System.out.println("%nReconnecting...");
CmdRun cmdRun = new CmdRun(command);
(new Thread(cmdRun)).start();
//...
}
};
public CmdRun(Object command) {
this.command = command;
this.runnable = executeAfter;
}
@Override
public void run() {
runnable.run();
}
}
class CmdRun实现可运行{
最终目标命令;
最终可运行;
最终可运行的executeAfter=()->{
如果(--重新连接<0){
System.out.println(“%n停止使用端口%d.”+端口);
//...
}否则{//请尝试重新连接
System.out.println(“%nReconnection…”);
CmdRun CmdRun=new CmdRun(命令);
(新线程(cmdRun)).start();
//...
}
};
公共CmdRun(对象命令){
this.command=命令;
this.runnable=executeAfter;
}
@凌驾
公开募捐{
runnable.run();
}
}
Runnable的run()不能包含自引用,因为它是非法的。
我不太确定你想要实现什么,但类似的事情应该会奏效:
class CmdRun implements Runnable {
final Object command;
final Runnable runnable;
final Runnable executeAfter = () -> {
if ( --reconnects < 0 ) {
System.out.println("%nStop using port %d." + port);
//...
} else { // try to reconnect
System.out.println("%nReconnecting...");
CmdRun cmdRun = new CmdRun(command);
(new Thread(cmdRun)).start();
//...
}
};
public CmdRun(Object command) {
this.command = command;
this.runnable = executeAfter;
}
@Override
public void run() {
runnable.run();
}
}
class CmdRun实现可运行{
最终目标命令;
最终可运行;
最终可运行的executeAfter=()->{
如果(--重新连接<0){
System.out.println(“%n停止使用端口%d.”+端口);
//...
}否则{//请尝试重新连接
System.out.println(“%nReconnection…”);
CmdRun CmdRun=new CmdRun(命令);
(新线程(cmdRun)).start();
//...
}
};
公共CmdRun(对象命令){
this.command=命令;
this.runnable=executeAfter;
}
@凌驾
公开募捐{
runnable.run();
}
}
简短回答:否
长答案:
你的代码会给你一个语法错误。为什么?lambda内部使用的executeAfter
未初始化;它仅在lambda定义的完整主体之后初始化
例如,考虑下面的例子。
int i;
sum(i, 5); // Syntax error!! Variable i is not initialized...
你的情况类似。在lambda内部,executeAfter
未初始化。如上所述,它仅在lambda定义的整个主体之后初始化
节点的另一件事是变量
reconnects
必须是final,才能在lambda中使用。如果它是最终变量,则不能在If条件内对其使用--
运算符 简短回答:否
长答案:
你的代码会给你一个语法错误。为什么?lambda内部使用的executeAfter
未初始化;它仅在lambda定义的完整主体之后初始化
例如,考虑下面的例子。
int i;
sum(i, 5); // Syntax error!! Variable i is not initialized...
你的情况类似。在lambda内部,executeAfter
未初始化。如上所述,它仅在lambda定义的整个主体之后初始化
节点的另一件事是变量
reconnects
必须是final,才能在lambda中使用。如果它是最终变量,则不能在If条件内对其使用--
运算符 这里必须有兰姆达吗?如果不是,切换到旧的等效语法应该很简单:
例如:
public class TestLambda {
static int count = 0;
public static void main(String[] args) {
// lambda not going to work
//Runnable foo = () -> { if (count < 5) { call(foo); } };
// nor
//Runnable foo = () -> { if (count < 5) { call(this); } };
// using old way of anonymous inner class will work
Runnable foo = new Runnable() {
@Override public void run() {
if (count < 5) {
call(this);
}
}
};
foo.run();
}
public static void call(Runnable action) {
count++;
System.out.println("in call " + count);
action.run();
}
}
公共类TestLambda{
静态整数计数=0;
公共静态void main(字符串[]args){
//lambda不工作了
//runnablefoo=()->{if(count<5){call(foo);};
//也不是
//runnablefoo=()->{if(count<5){调用(this);};
//使用匿名内部类的旧方法将起作用
Runnable foo=new Runnable(){
@重写公共无效运行(){
如果(计数小于5){
叫(这个);
}
}
};
foo.run();
}
公共静态无效调用(可运行操作){
计数++;
系统输出打印项次(“输入呼叫”+计数);
action.run();
}
}
这里必须有lambda吗?如果不是,切换到旧的等效语法应该很简单:
例如:
public class TestLambda {
static int count = 0;
public static void main(String[] args) {
// lambda not going to work
//Runnable foo = () -> { if (count < 5) { call(foo); } };
// nor
//Runnable foo = () -> { if (count < 5) { call(this); } };
// using old way of anonymous inner class will work
Runnable foo = new Runnable() {
@Override public void run() {
if (count < 5) {
call(this);
}
}
};
foo.run();
}
public static void call(Runnable action) {
count++;
System.out.println("in call " + count);
action.run();
}
}
公共类TestLambda{
静态整数计数=0;
公共静态void main(字符串[]args){
//lambda不工作了
//runnablefoo=()->{if(count<5){call(foo);};
//也不是
//runnablefoo=()->{if(count<5){调用(this);};
//使用匿名内部类的旧方法将起作用
Runnable foo=new Runnable(){
@重写公共无效运行(){
如果(计数小于5){
叫(这个);
}
}
};
foo.run();
}
公共静态无效调用(可运行操作){
计数++;
系统输出打印项次(“输入呼叫”+计数);
action.run();
}
}
实际上,如果您不介意引入新的界面(或者如果您更经常地需要此类功能),您可以使用以下功能:
@FunctionalInterface
interface RecursiveRunnable extends Runnable {
default void run() {
run(this);
}
public void run(RecursiveRunnable runnable);
}
这将允许您递归调用runnable,例如:
int maxTries = 3;
AtomicInteger counter = new AtomicInteger();
RecursiveRunnable foo = runnable -> {
if (counter.getAndIncrement() < maxTries) {
println("Reconnecting... %n");
runnable.run(); // same as: runnable.run(runnable)
} else {
println("Stop using port %d%n", port);
}
};
int最大值