我有一个需要一段时间才能完成的方法。我希望我的方法在返回“最终”结果之前返回“初步”结果。
我想了解是否有可能这样做:
public Object myMethod () {
/*some computation here*/
return firstResult;
/*
very long computation here
*/
return finalResult;
}
这甚至可能吗,或者您可以建议某种解决方法吗?
我有一个需要一段时间才能完成的方法。我希望我的方法在返回“最终”结果之前返回“初步”结果。
我想了解是否有可能这样做:
public Object myMethod () {
/*some computation here*/
return firstResult;
/*
very long computation here
*/
return finalResult;
}
这甚至可能吗,或者您可以建议某种解决方法吗?
您可以将长时间运行的任务放在执行程序上(它将使用线程池异步执行任务)并返回一个Future,您可以稍后使用它来获得答案。当您调用get
未来时,它会阻塞直到任务完成,因此您可以立即使用您的初始答案,并Future.get
在以后需要更精确时调用,给任务一些时间来完成。
返回值可能如下所示:
class MyMethodReturnStuff {
private Object quickAnswer;
private Future longAnswer;
private long startTime = System.currentTimeMillis();
MyMethodReturnStuff(Object quickAnswer, Future longAnswer) {
this.quickAnswer = quickAnswer;
this.longAnswer = longAnswer;
}
Object getAnswer(long expectedDelay) {
return System.currentTimeMillis() - startTime < expectedDelay ?
quickAnswer : longAnswer.get();
}
}
如果您预计长计算需要 5 秒,getAnswer(5000)
如果不到 5 秒,调用将返回快速答案,否则将返回 longAnswer。
你不能简单地使用两种不同的方法吗?
public class Computer {
private String commonVar1;
private int commonVar2;
public Object shortComput() {
// short comput using commonVar1 and commonVar2
return firstResult;
}
public Object longComput() {
// long comput using commonVar1 and commonVar2
return finalResult;
}
}
调用时:
Computer c = new Computer();
Object firstResult = c.shortComput();
// do some short stuff with firstResult before launching:
Object finalResult = c.longComput();
不,这是不可能的,一个函数只能返回一次。一旦它返回,后续代码将不会被执行。但是,您可以更改代码设计,改为将输出写入参数引用的数据结构/放置为类成员。例如:
public void longRunningFunc(List<String> output) {
// some computation here
output.add(..);
// very long computation here
output.add(..);
}
是的。SwingWorker
是要走的路。
如果您不熟悉SwingWorker
,它基本上是一个可以让您运行长时间计算的类。他们可以在完成后给出结果,或者在此过程中发布中期结果,这基本上就是你想要做的。
来自Java 教程的“具有临时结果的任务”部分:
在后台任务仍在工作时提供临时结果通常很有用。该任务可以通过调用 SwingWorker.publish 来完成。此方法接受可变数量的参数。每个参数必须是 SwingWorker 的第二个类型参数指定的类型。
例如:_
private class FlipTask extends SwingWorker<Void, FlipPair> {
@Override
protected Void doInBackground() {
long heads = 0;
long total = 0;
Random random = new Random();
while (!isCancelled()) {
total++;
if (random.nextBoolean()) {
heads++;
}
// Here's your interim result, your "first return statement"
publish(new FlipPair(heads, total));
}
return null;
}
@Override
protected void process(List<FlipPair> pairs) {
FlipPair pair = pairs.get(pairs.size() - 1);
headsText.setText(String.format("%d", pair.heads));
totalText.setText(String.format("%d", pair.total));
devText.setText(String.format("%.10g",
((double) pair.heads)/((double) pair.total) - 0.5));
}
}
如果由于某种原因您不能使用SwingWorker
,则需要使用异步线程来执行此操作。您可以尝试以下方法:
interface Callback {
public void computationComplete(Result r);
}
public Result doComputation(final Callback c) {
// Do computation
new Thread(new Runnable() {
@Override
public void run() {
// Complete computation
c.computationComplete(finalResult);
}
}).start();
return firstResult;
}
但这基本上是在重新发明轮子。
我会使用侦听器模式。可以将自定义侦听器实例传递到方法中或添加到对象中。当长时间运行的方法执行时,您可以适当地调用侦听器,传递您需要的任何信息。可以多次调用此侦听器。
这在 Java 中绝对是不可能的。你为什么不简单地将你的方法分成两个不同的方法呢?
只需使用一个条件:
public class TestMethod {
public static void main(String[] args)
{
boolean yes=false;
int something=compute(yes);
System.out.println(something);
yes=true;
something=compute(yes);
System.out.println(something);
}
public static int compute(boolean yes)
{
if(!yes)
{
System.out.println("1st block");
return 22;
}
else
{
System.out.println("2nd block");
return 33;
}
}
}
编辑: 根据问题,我使用了一种方法:从方法中多次返回。
这是可能的,但你必须引入线程。
您的应用程序应该有两个线程main
和worker
.
线程,是你的main
整个程序。那是在他工作期间开始的worker
。Worker 进行计算,在第一部分之后他可以设置一个main
线程可以读取和显示的值。