2013-03-29 7 views
7

私は完了までに時間がかかる方法があります。私は自分のメソッドが "最終的な"結果を返す前に "予備的な"結果を返すことを望みます。メソッドから何回も返されますか?

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

    return firstResult; 

    /* 
    very long computation here 
    */ 

    return finalResult; 
} 

がこのさえ可能ですか、回避策のいくつかの種類を提案することができます:

私はそれがこのようなものにできるかどう理解したいと思いますか?

+0

なぜ 'myMethod()'を2回呼び出さないのですか?最初に変数を取り、2番目のコードブロックを実行しないようにfalseにします。 –

+0

メソッドから予期しない動作が予想されます。 –

+0

あなたの質問を明確にし、GUIに関連するような背景情報を提供してください。アンドロイド?何か完全に? –

答えて

6

executor(スレッドプールを使用してタスクを非同期に実行する)に長期実行タスクを配置し、後で答えを得るために使用できるFutureを返すことができます。今後getに電話すると、タスクが終了するまでブロックされるので、すぐに初期回答を使用して、後で精度を高める必要がある場合はFuture.getに電話をかけてください。

戻り値は次のようになります。あなたが長い計算が5秒かかることが予想される場合getAnswer(5000)が5秒未満が経過した場合の迅速な答えを返しますし、そうでない場合はlongAnswerを返す呼び出し、

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

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(); 
+0

しかし、 'longComput'は以前に' shortComput'で実行された計算をやり直さなければならないかもしれませんし、その間に結果が変更されていないという仮定に頼っているかもしれません。 – wchargin

+0

@WCharginコンピュータのフィールドに計算結果を保存しない場合。また、複数のスレッドが同時に使用することができない場合、結果は変更されません。 – sp00m

+0

''いくつかの短いstuff'コードで変更できませんでしたか? – wchargin

2

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

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

    // very long computation here 
    output.add(..); 
} 
2

はい。 SwingWorkerは行く方法です。

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

Javaチュートリアルのセクション"Tasks that Have Interim Results,"から:それは多くの場合、それはまだ働いている間に中間結果を提供するために、バックグラウンドタスクのために有用である

。このタスクは、SwingWorker.publishを呼び出すことで実行できます。このメソッドは、可変数の引数を受け入れます。各引数は、SwingWorkerの第2の型パラメータで指定された型でなければなりません。 exampleについては

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

これは基本的に車輪を再発明しています。

+2

この質問にSwingが関係することをどのように知っていますか? –

1

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

1

これはJavaでは不可能です。なぜあなたは2つの異なるメソッドでメソッドを分割しないのですか?

+2

これは間違いなくJavaで可能です! –

-2

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

アプリケーションには、2つのスレッドmainworkerが必要です。

スレッドmainスレッドは、あなたのプログラム全体です。それは彼の仕事の間にworkerを始めます。作業者は計算を行い、最初の部分の後にmainスレッドが読み取りおよび表示できる値を設定できます。

+0

、つまり、SwingWorkerを使用します。なぜ車を改革するのですか? – wchargin

+0

SwingWorkerはこの作業に適したツールです。 –

+0

あなたは 'one'メソッドが' two'の結果を返す方法をまだ見せていません:/ – A4L

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

} 
} 

EDIT: 私は質問ごとに単一のメソッドを使用している:メソッドから複数回を返します。

+2

いいえ、代わりに2つの方法が必要です。これは基本的に本当に間違っています。 –

+1

あなたが提示したコードは実際にはあまり設計されていません。静的フラグを使用して、引数として宣言できるメソッドに値を渡します。将来的にはそれを使ってロジックを分割します。 method1とmethod2を宣言して順番に呼び出すのと同じことです。これは単一の大きな方法(それも悪い)に減らすことができます。結論は、あなたの例では問題を解決せず、コードを読みにくくすることです。 –

+0

@Vash私はあなたが質問を慎重に読んでいないと思う。 "_方法_"それはなぜ単一の方法を使用したか) –

関連する問題