5

プリアンブル: リストまたはその他のコレクションを使用して結果を返すことは承知していますが、リストを調べて結果を抜き出す必要があります: 2 番目の例を参照してください

Preamble-2: 「これは Java ではサポートされていません ...」以外の回答を探しています。


Java メソッド呼び出しから複数のオブジェクトを返す便利な方法を探しています。

PHPのようなもの:

list ($obj1, $obj2, ...) foobar();

たとえば、引数でホルダーオブジェクトを渡すのに本当にうんざりしています:

class Holder {
   int value;
}

Holder h1=new Holder();
Holder h2=new Holder();

その後:

o.foobar(h1,h2);

...誰かがこれを回避するエレガントな方法を考え出した場合、非常に興味があります。


リストの使用

List<String> = foobar();

これには 2 つの欠点があります。

最初に家の呼び出し先側で List をパックする必要があります。

// this is on the callee side of the house
ArrayList<String> result = new ArrayList<String>
result.add("foo");
result.add("bar");

次に、呼び出し側で結果を取り出す必要があります。

// This is on the caller side
List<String> result = foobar();
String result1 = result.get(0);
String result2 = result.get(1); // this is not as elegant as the PHP equivalent

さらに、文字列、整数など、さまざまなタイプのオブジェクトを返したいとします。オブジェクトのリストを返してから、各オブジェクトをキャストする必要があります...きれいではありません

ありがとう。

4

6 に答える 6

9

ジェネリック タプル クラスを使用することは、私が想像できる最も近いものです。アイデアを与えるために、このような 3 つの戻り値の汎用クラスは次のようになります。

public class T3<A, B, C> {
    A _1;
    B _2;
    C _3;
    T3(A _1, B _2, C _3) {
        this._1 = _1;
        this._2 = _2;
        this._3 = _3;
    }
}

これにより、呼び出し先側で 1 つのステートメント コンストラクターを使用できます。たとえば、次のようになります。

public T3<String, Integer, Character> getValues() {
    return new T3<String, Integer, Character>("string", 0, 'c');
}

ただし、呼び出し先によるホルダー インスタンスの構築は行われません。

戻り値の数ごとに、独自の tuple-class が必要です。Functional Java ライブラリで提供されているようなものがあるかもしれません。参考までに、N タプルの実装を次に示します。

値が 2 つの場合、java.util.AbstractMap.SimpleEntry は次のようになります。

return new SimpleEntry<String, Integer>("string", 0);

とにかく、複数の戻り値について考慮すべき重要な点が 2 つあります。

  1. 型付きの戻り値
  2. 各戻り値の意味を指摘する

つまらないことですが、別のクラスを作成してすべての応答値を保持し、それをメソッドの戻り値の型として宣言することをお勧めします。そうすれば、各値の意味を強調することができます。

于 2012-05-13T22:13:32.473 に答える
5

次のようなシグネチャを持つメソッドを使用できます。

List<Holder> foobar();
于 2012-05-13T19:26:26.743 に答える
4

ListSet、またはを返すことができますかMap?

于 2012-05-13T19:25:49.153 に答える
2

同じタイプの複数の値を返す必要がある場合は、リストまたはセットが適切です。たとえば、可変長のユーザー名リストをリストとして返すことは完全に有効です。常に固定数の値を返すことがわかっている場合は、配列を使用します。たとえば、ある種のユーザーIDを3つの異なる整数として返すメソッドでは、次のように使用します。

public int[] getUserId(){
    int[] returnArray = new int[3];
    returnArray[0] = getFirstPart();
    returnArray[1] = getSecondPart();
    returnArray[2] = getThirdPart();

    return returnArray;
}

array[0]呼び出し元のコードでは、値の取得は、、array[1]およびと同じくらい簡単array[2]です。これはコレクションよりもはるかに簡単で、ユーザーIDは3つの整数として定義されているため、何も壊すことはありません。

本当に複数の異なる値を返す必要がある場合は、ホルダークラスが最適なオプションであり、それを回避する方法は他にありません。Javaでは複数の戻り値はサポートされていません。しかし、私はむしろ設計の観点からソリューションを見たいと思います。クラスが複数の異なる値を返す必要がある場合、それはおそらく多くのことを行い、そのいくつかは他とは無関係です。単一のコード(クラス、メソッド)には、常に単一の明確な目的と明確に定義された責任が必要です。複数の異なる値を返すのではなく、メソッドを複数の短いメソッドに分割するか、すべての機能を外部化するためのインターフェイスを定義することを検討します。これらの戻り値が何らかの形で関連していて、分解しても意味がない場合は、それ自体でクラスに値すると思います。

于 2012-05-13T20:59:18.720 に答える
2

拡張されたホルダーを返すことは、リストを返すよりも優れているようです:

class Holder {
    int value1;
    String value2;
    Holder(int value1, String value2) {}
}

Holder foobar() {
    return new Holder(1, "bar");
}
于 2012-05-13T20:10:49.730 に答える
1

この目的のために任意のCollectionクラスを使用できます。このレッスンは、あなたに最適なものを決定するのに役立ちます。

于 2012-05-13T19:37:23.897 に答える