7

完了するまでに時間がかかる方法があります。「最終」結果を返す前に、メソッドが「予備」結果を返すようにしたいと考えています。

次のようなことが可能かどうかを理解したいと思います。

public Object myMethod () {
    /*some computation here*/

     return firstResult;

     /*
     very long computation here
     */

     return finalResult;
}

これは可能ですか、または何らかの回避策を提案できますか?

4

8 に答える 8

6

実行時間の長いタスクをエグゼキューター (スレッド プールを使用してタスクを非同期的に実行する) に置き、後で答えを得るために使用できるFutureを返すことができます。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 が返されます。

于 2013-03-29T16:11:34.627 に答える
3

単純に 2 つの異なる方法を使用することはできませんか?

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();
于 2013-03-29T16:08:59.203 に答える
2

いいえ、それは不可能です。関数は 1 回しか返せません。返されると、後続のコードは実行されません。ただし、コード設計を変更して、代わりにクラス メンバーとして配置された引数によって参照されるデータ構造に出力を書き込むことができます。例えば:

public void longRunningFunc(List<String> output) {
  // some computation here
  output.add(..);

  // very long computation here
  output.add(..);
}
于 2013-03-29T16:09:03.800 に答える
2

はい。SwingWorker行く方法です。

に慣れていない場合SwingWorker、これは基本的に長時間実行される計算を実行できるクラスです。彼らは、完了したときに結果を出すか、途中で中間結果を公開することができます。これは基本的にあなたがやろうとしていることです.

Javaチュートリアルのセクション「中間結果を持つタスク」から:

バックグラウンド タスクがまだ動作している間に中間結果を提供すると便利なことがよくあります。タスクは、SwingWorker.publish を呼び出すことでこれを行うことができます。このメソッドは、可変数の引数を受け入れます。各引数は、SwingWorker の 2 番目の型パラメーターで指定された型でなければなりません。

: _

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;
}

しかし、これは基本的に車輪の再発明です。

于 2013-03-29T16:09:41.577 に答える
1

リスナーパターンを使用します。カスタム リスナー インスタンスは、メソッドに渡すか、オブジェクトに追加できます。長期実行メソッドが実行されると、必要な情報を渡して適切にリスナーを呼び出すことができます。このリスナーは何度でも呼び出すことができます。

于 2013-03-29T16:09:46.070 に答える
1

単純に条件を使用します。

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;
}

}
}

編集: 私は質問に従って単一のメソッドを使用しました:メソッドから複数回戻ります。

于 2013-03-29T16:14:46.010 に答える
1

これはJavaでは絶対に不可能です。メソッドを 2 つの異なるメソッドに単純に分割してみませんか?

于 2013-03-29T16:10:05.860 に答える
-2

これは可能ですが、スレッドに導入する必要があります。

アプリケーションには 2 つのスレッドmainworker.

スレッドは、mainプログラム全体です。彼の仕事中にそれを開始しworkerます。mainワーカーは計算を行い、最初の部分の後、スレッドが読み取って表示できる値を設定できます。

于 2013-03-29T16:12:51.847 に答える