Java 具有可变参数的方法,执行操作并打印已知结果
Java method with varargs that executes actions and prints known result
是否可以在 Java 中创建类似于此 execute 方法的方法:
public void execute(Runnable... mrs) {
for (Runnable mr : mrs) {
mr.run();
// should print some expected string here
}
}
public void sleep(int seconds) {
try {
Thread.sleep(1000 * seconds);
} catch (InterruptedException ex) {
log.error("Error occured", ex);
}
}
public void customExecute() {
execute(() -> sleep(1), () -> sleep(2));
}
但在执行每个操作后,它应该打印传递的 String 参数,并且(问题的关键时刻)它应该支持一行用法 - 类似于:
execute(("Action 1 passed") -> someAction(), ("Other action passed") -> otherAction());
Java 没有将键值对传递给方法的特殊语法。我看到两种可能的解决方案。
1。创建附加对象:
static class NamedRunnable implements Runnable {
Runnable r;
String title;
public NamedRunnable(String title, Runnable r) {
this.title = title;
this.r = r;
}
@Override
public void run() {
r.run();
}
@Override
public String toString() {
return title;
}
}
public void execute(NamedRunnable... mrs) {
for (NamedRunnable mr : mrs) {
mr.run();
System.out.println(mr+" completed");
}
}
public void customExecute() {
execute(new NamedRunnable("Action 1 passed", () -> sleep(1)),
new NamedRunnable("Other action passed", () -> sleep(2)));
}
面向对象,但不是很短
2。用不同数量的参数声明几个 execute
方法。
public void execute(String t1, Runnable r1) {
execute(new NamedRunnable(t1, r1));
}
public void execute(String t1, Runnable r1, String t2, Runnable r2) {
execute(new NamedRunnable(t1, r1),
new NamedRunnable(t2, r2));
}
public void execute(String t1, Runnable r1, String t2, Runnable r2,
String t3, Runnable r3) {
execute(new NamedRunnable(t1, r1),
new NamedRunnable(t2, r2),
new NamedRunnable(t3, r3));
}
// continue if you need more
public void customExecute() {
execute("Action 1 passed", () -> sleep(1), "Other action passed", () -> sleep(2));
}
这里的调用看起来更简洁,但它需要更多的“库”代码。
您可以使用构建器模式的变体来做到这一点:
public interface Step {
void doIt(String msg, Runnable r);
default Step then(String msg, Runnable r) {
doIt(msg, r);
return this;
}
}
public static Step execute(String msg, Runnable r) {
Step s=(m,x)-> {
x.run();
System.out.println(msg);
};
return s.then(msg, r);
}
那你就可以像
一样使用它
execute("Action 1 passed", () -> someAction())
.then("Other action passed", () -> otherAction());
随意扩展
execute("Action 1 passed", () -> someAction())
.then("Other action passed", () -> otherAction())
.then("NextAction passed", () -> nextAction())
.then("and nextAction passed again", () -> nextAction()) ;
它也很容易适应其他执行策略,例如
static ExecutorService es=Executors.newSingleThreadExecutor();
public static Step executeInBackground(String msg, Runnable r) {
Step s=(m,x)-> es.execute(()-> execute(m, x));
return s.then(msg, r);
}
调用方稍作改动即可使用:
executeInBackground("Action 1 passed", () -> someAction())
.then("Other action passed", () -> otherAction())
.then("NextAction passed", () -> nextAction())
.then("and nextAction passed again", () -> nextAction());
这是一个使用可变参数和高阶函数的变体。它比 Holger 的更简单(但也更不通用)。但是,如果您只想在执行 Runnable
.
后打印一个字符串,这可能就足够了
这个想法是有一个函数,它通过获取现有的并在 运行 之后打印一个字符串来创建一个新的 Runnable
它:
static Runnable runPrint(Runnable r, String msg) {
return () -> {
r.run();
System.out.println(msg);
};
}
然后您只需将其中几个传递给基于可变参数的 execute
方法:
execute(runPrint(() -> sleep(1), "first"),
runPrint(() -> sleep(2), "second"),
runPrint(() -> sleep(3), "third"));
是否可以在 Java 中创建类似于此 execute 方法的方法:
public void execute(Runnable... mrs) {
for (Runnable mr : mrs) {
mr.run();
// should print some expected string here
}
}
public void sleep(int seconds) {
try {
Thread.sleep(1000 * seconds);
} catch (InterruptedException ex) {
log.error("Error occured", ex);
}
}
public void customExecute() {
execute(() -> sleep(1), () -> sleep(2));
}
但在执行每个操作后,它应该打印传递的 String 参数,并且(问题的关键时刻)它应该支持一行用法 - 类似于:
execute(("Action 1 passed") -> someAction(), ("Other action passed") -> otherAction());
Java 没有将键值对传递给方法的特殊语法。我看到两种可能的解决方案。
1。创建附加对象:
static class NamedRunnable implements Runnable {
Runnable r;
String title;
public NamedRunnable(String title, Runnable r) {
this.title = title;
this.r = r;
}
@Override
public void run() {
r.run();
}
@Override
public String toString() {
return title;
}
}
public void execute(NamedRunnable... mrs) {
for (NamedRunnable mr : mrs) {
mr.run();
System.out.println(mr+" completed");
}
}
public void customExecute() {
execute(new NamedRunnable("Action 1 passed", () -> sleep(1)),
new NamedRunnable("Other action passed", () -> sleep(2)));
}
面向对象,但不是很短
2。用不同数量的参数声明几个 execute
方法。
public void execute(String t1, Runnable r1) {
execute(new NamedRunnable(t1, r1));
}
public void execute(String t1, Runnable r1, String t2, Runnable r2) {
execute(new NamedRunnable(t1, r1),
new NamedRunnable(t2, r2));
}
public void execute(String t1, Runnable r1, String t2, Runnable r2,
String t3, Runnable r3) {
execute(new NamedRunnable(t1, r1),
new NamedRunnable(t2, r2),
new NamedRunnable(t3, r3));
}
// continue if you need more
public void customExecute() {
execute("Action 1 passed", () -> sleep(1), "Other action passed", () -> sleep(2));
}
这里的调用看起来更简洁,但它需要更多的“库”代码。
您可以使用构建器模式的变体来做到这一点:
public interface Step {
void doIt(String msg, Runnable r);
default Step then(String msg, Runnable r) {
doIt(msg, r);
return this;
}
}
public static Step execute(String msg, Runnable r) {
Step s=(m,x)-> {
x.run();
System.out.println(msg);
};
return s.then(msg, r);
}
那你就可以像
一样使用它execute("Action 1 passed", () -> someAction())
.then("Other action passed", () -> otherAction());
随意扩展
execute("Action 1 passed", () -> someAction())
.then("Other action passed", () -> otherAction())
.then("NextAction passed", () -> nextAction())
.then("and nextAction passed again", () -> nextAction()) ;
它也很容易适应其他执行策略,例如
static ExecutorService es=Executors.newSingleThreadExecutor();
public static Step executeInBackground(String msg, Runnable r) {
Step s=(m,x)-> es.execute(()-> execute(m, x));
return s.then(msg, r);
}
调用方稍作改动即可使用:
executeInBackground("Action 1 passed", () -> someAction())
.then("Other action passed", () -> otherAction())
.then("NextAction passed", () -> nextAction())
.then("and nextAction passed again", () -> nextAction());
这是一个使用可变参数和高阶函数的变体。它比 Holger 的更简单(但也更不通用)。但是,如果您只想在执行 Runnable
.
这个想法是有一个函数,它通过获取现有的并在 运行 之后打印一个字符串来创建一个新的 Runnable
它:
static Runnable runPrint(Runnable r, String msg) {
return () -> {
r.run();
System.out.println(msg);
};
}
然后您只需将其中几个传递给基于可变参数的 execute
方法:
execute(runPrint(() -> sleep(1), "first"),
runPrint(() -> sleep(2), "second"),
runPrint(() -> sleep(3), "third"));