Javaでは複数の値がどのように返されますか?


11

関数から複数の値を返したい場合があります。 これは通常 Javaでどのように行われますか?

1つのオプションは、リストまたはタプルを返すこのPythonスニペットのような配列を使用することです。

value, success = read_unreliably()
if success:
    print value

別のオプションは、次のJavaScriptの例のように、ハッシュ/辞書を返すことです。

var result = readUnreliably()
if (result.success) {
    alert(value);
}

もう1つは、このJavaの例のように、この目的のためだけにカスタムオブジェクトを作成することです。

ReadUnreliablyResult result = readUnreliably()
if (result.getSuccess()) {
    System.out.println(result.getValue());
}

もちろん、物事をやり取りする代わりに、いくつかのグローバル変数を使用して必要なものを保存することもできますが、それはオプションではないと言ってみましょう。


「本当の」Javaの人々は、そのような小さな内部クラスのフィールドを隠すために、パブリックゲッターとセッターを使用するという問題を本当に経験しますか?ちょっと興味があるんだけど。
クリスファーマー

3
はい、ほとんどが行います。多くのフレームワークはJavaBean標準を想定しているため、ゲッターとセッターがないことを後悔できます。いずれにしても、IDEがそれらを生成します。
エリックウィルソン

3
または、YAGNIの原則に基づいて、それらを単に省略できます。しかし、それは予想されるほど頻繁には起こらないようです。
MatrixFrog

@FarmBoy:Beanなどについては理解していると思いますが、OPは、これが複数の値を返すように設計された1回限りのクラスであることを示唆しています。
クリスファーマー

@ChrisFarmerそのコンテキストでは、「実際の」Javaプログラマーがこの目的のためにクラスを作成するのを見たことがないと思います。
エリックウィルソン

回答:


26

これは通常Javaでどのように行われますか?

痛い。

1つのオプションは、リストまたはタプルを返すこのPythonスニペットのような配列を使用することです...

別のオプションは、このJavaScriptの例のように、ハッシュ/ dictを返すことです...

これらの手法はJavaではうまく機能しません。値はオブジェクトからダウンキャストする必要があります。

もう1つは、このJavaの例のように、この目的のためだけにカスタムオブジェクトを作成することです...

これは最も一般的ですが、これらの小さなクラスをすべて作成するのは面倒です。C ++ではstd :: pairを使用するのが一般的ですが、これはJavaでは一般的に行われません。

ロンボク少しのカスタムオブジェクトを作成することは非常に簡単です:

@RequiredArgsConstructor
public class X {
  private final boolean status;
  private final byte[] data;

}


10
「これは通常Javaでどのように行われますか?」「痛々しい。」笑Java開発者として、そのために+1する必要があります
-TheLQ

コンパクトな不変のstruct-likeクラスを使用するのはそれほど苦痛ではありません...それは本当にCのstructを書くようなものです
Guillaume

1
@Guillaume-確かに、しかし、それらのささいなことはすべて時間と空間の両方で増えます。Javaコミュニティが「class Pair <T1、T2> {public T1 first; public T2 second; ...}」のようなジェネリックの標準セットを採用していない理由はわかりません。現代の言語では、「a、bを返す」だけです。そして「x、y = f()」と書く;
ケビンクライン

1
私はいくつかの「古代の」言語もそれを行うことができると確信しています:)私見複数の戻り値が全体の混乱につながる可能性があり、別の戻りフィールドを追加する必要がある場合は、クラスのような構造体を更新する必要がありますメソッドのシグネチャを変更します。
ギヨーム

1
それは「痛みを伴う」。似たような状況に出会ったときにJava開発者として感じていることとまったく同じです。
artjom

13

はい、Javaでstruct/ tuple/ を作成する方法recordは、クラスを作成することです。内部でのみ使用する場合は、パブリックフィールドを持つ小さな不変の構造体のようなクラスを使用することを好みます。

例:

public class Unreliably {
    public final boolean success;
    public final int value;
    public Unreliably(boolean success, int value) {
        this.success = success; this.value = value;
    }
}

これはScalaで行う方がはるかに簡単です:

case class Unreliably(success: Boolean, value: Int)

8
実際、Scalaでは、通常は単にを返しますTuple2[Boolean, Int]。この特定の例では、を返しますOption[Int]
ヨルグWミットタグ

2
したがって、これは、実際のJavaの人々は必ずしも小さな内部クラスのゲッターとセッターを作成するとは限らないというChris Farmerの質問(Qのコメント)に答えています。あなたは「本当の」Javaの人ですよね?
マイクM.リン

2
他のニュースでは、真のスコットランド人はいません。
ジョセフワイスマン

5

あなたが与えた例では、例外を投げることがそれを処理する最も標準的な方法です:

try {
    result = readUnreliably();
    System.out.println(result);
} (catch IOException e) {
    System.out.println("Could not read file");
}

さらに、「Do One Thing」機能を実行しようとすると、複数の値を返す機能はあまり必要ではありませんが、ときどき便利になります。


4

Aの1つのインスタンスとBの1つのインスタンスを格納できるPairジェネリッククラスがあります。おそらく、同じ方法で3連符または4連符を作成できます。

public class Pair<A, B>
{
    ...
}

1
ただし、これにより、実際には読み取り不可能なコードが作成されます。メソッドがを返す場合、Pair<String, Integer>それはどういう意味ですか?これらの値は何を表していますか?メソッドの実装を読まずに知ることはできません。
サラ

1

Javaでは、関数はオブジェクトを返します(失敗した場合はnullもあります)。これにより、複数のデータを返すことができます。


1

Javaで複数の変数を返す明示的な方法はありませんが、いくつかのアプローチがあります。

  1. 1つ目は、配列の方法です。これは、すべてが同じデータ型であるか、一時的に1つの型に変換できる場合にのみ有効です。
  2. 2番目の方法は、複数の変数タイプを転送するためのクラスを作成することです。私の仕事では、これらをDTOまたはデータ転送オブジェクトと呼びます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.