Javaメソッドから複数の値を返す方法

1。概要

このチュートリアルでは、Javaメソッドから複数の値を返すさまざまな方法を学習します。

まず、配列とコレクションを返します。次に、複雑なデータにコンテナクラスを使用する方法を示し、ジェネリックタプルクラスを作成する方法を学習します。

最後に、サードパーティのライブラリを使用して複数の値を返す方法の例を示します。

2.配列の使用

配列を使用して、プリミティブデータ型と参照データ型の両方を返すことができます

たとえば、次のgetCoordinatesメソッドは、2つのdouble値の配列を返します。

double[] getCoordinatesDoubleArray() { double[] coordinates = new double[2]; coordinates[0] = 10; coordinates[1] = 12.5; return coordinates; }

異なる参照型の配列を返したい場合は、配列の型として共通の親型を使用できます

Number[] getCoordinatesNumberArray() { Number[] coordinates = new Number[2]; coordinates[0] = 10; // Integer coordinates[1] = 12.5; // Double return coordinates; }

ここでは、整数要素と倍精度要素の間の共通クラスであるため、数値型の座標配列を定義しました。

3.コレクションの使用

ジェネリックJavaコレクションを使用すると、共通タイプの複数の値を返すことができます

コレクションフレームワークには、幅広いクラスとインターフェイスがあります。ただし、このセクションでは、説明をリストインターフェイスとマップインターフェイスに限定します。

3.1。リスト内の同様のタイプの戻り値

まず、Listを使用して前の配列の例を書き直してみましょう。

List getCoordinatesList() { List coordinates = new ArrayList(); coordinates.add(10); // Integer coordinates.add(12.5); // Double return coordinates; }

Number []と同様に、Listコレクションは、すべて同じ共通タイプの混合タイプ要素のシーケンスを保持します。

3.2。マップで名前付きの値を返す

コレクション内の各エントリに名前を付ける場合は、代わりにマップを使用できます。

Map getCoordinatesMap() { Map coordinates = new HashMap(); coordinates.put("longitude", 10); coordinates.put("latitude", 12.5); return coordinates; }

getCoordinatesMapメソッドのユーザーは、Map#getメソッドで「経度」または「緯度」キーを使用して、対応する値を取得できます。

4.コンテナクラスの使用

配列やコレクションとは異なり、コンテナクラス(POJO)は、異なるデータ型で複数のフィールドをラップできます

たとえば、次のCoordinatesクラスには、doubleStringの2つの異なるデータ型があります。

public class Coordinates { private double longitude; private double latitude; private String placeName; public Coordinates(double longitude, double latitude, String placeName) { this.longitude = longitude; this.latitude = latitude; this.placeName = placeName; } // getters and setters }

Coordinatesのようなコンテナクラスを使用すると、意味のある名前を持つ複雑なデータ型をモデル化できます

次のステップは、Coordinatesのインスタンスをインスタンス化して返すことです。

Coordinates getCoordinates() { double longitude = 10; double latitude = 12.5; String placeName = "home"; return new Coordinates(longitude, latitude, placeName); }

私たちは、ことに注意しなければならない、私たちのようなデータクラスにすることをお勧めします座標不変。そうすることで、シンプルでスレッドセーフな共有可能なオブジェクトを作成します。

5.タプルの使用

コンテナと同様に、タプルはさまざまなタイプのフィールドを格納します。ただし、アプリケーション固有ではないという点で異なります

これらは、処理するタイプを記述するために使用する場合に特化されていますが、特定の数の値の汎用コンテナーです。つまり、カスタムコードを記述してそれらを作成する必要はなく、ライブラリを使用することも、共通の単一の実装を作成することもできます。

タプルは任意の数のフィールドにすることができ、しばしばタプルnと呼ばれます。ここで、nはフィールドの数です。たとえば、Tuple2は2フィールドのタプル、Tuple3は3フィールドのタプルなどです。

タプルの重要性を示すために、次の例を考えてみましょう。座標点とリスト内の他のすべての点との間の距離を見つけたいとします。次に、その最も遠いCoordinateオブジェクトを距離とともに返す必要があります。

Let's first create a generic two-fields tuple:

public class Tuple2 { private K first; private V second; public Tuple2(K first, V second){ this.first = first; this.second = second; } // getters and setters }

Next, let's implement our logic and use a Tuple2 instance to wrap the results:

Tuple2 getMostDistantPoint(List coordinatesList, Coordinates target) { return coordinatesList.stream() .map(coor -> new Tuple2(coor, coor.calculateDistance(target))) .max((d1, d2) -> Double.compare(d1.getSecond(), d2.getSecond())) // compare distances .get(); }

Using Tuple2 in the previous example has saved us from creating a separate container class for one-time use with this particular method.

Like containers, tuples should be immutable. Additionally, due to their general-purpose nature, we should use tuples internally rather than as part of our public API.

6. Third-Party Libraries

Some third-party libraries have implemented an immutable Pair or Triple type. Apache Commons Lang and javatuples are prime examples. Once we have those libraries as dependencies in our application, we can directly use the Pair or Triple types provided by the libraries instead of creating them by ourselves.

Let's look at an example using Apache Commons Lang to return a Pair or a Triple object.

Before we step further, let's add the commons-lang3 dependency in our pom.xml:

 org.apache.commons commons-lang3 3.9 

6.1. ImmutablePair from Apache Commons Lang

The ImmutablePair type from Apache Commons Lang is exactly what we want: an immutable type whose usage is straightforward.

It contains two fields: left and right. Let's see how to make our getMostDistantPoint method return an object of the ImmutablePair type:

ImmutablePair getMostDistantPoint( List coordinatesList, Coordinates target) { return coordinatesList.stream() .map(coordinates -> ImmutablePair.of(coordinates, coordinates.calculateDistance(target))) .max(Comparator.comparingDouble(Pair::getRight)) .get(); }

6.2. ImmutableTriple from Apache Commons Lang

The ImmutableTriple is pretty similar to the ImmutablePair. The only difference is, as its name tells, an ImmutableTriple contains three fields: left, middle, and right.

Now, let's add a new method to our coordinates calculation to show how to use the ImmutableTriple type.

We're going to go through all points in a List to find out the min, avg, and max distances to the given target point.

Let's see how can we return the three values with a single method using the ImmutableTriple class:

ImmutableTriple getMinAvgMaxTriple( List coordinatesList, Coordinates target) { List distanceList = coordinatesList.stream() .map(coordinates -> coordinates.calculateDistance(target)) .collect(Collectors.toList()); Double minDistance = distanceList.stream().mapToDouble(Double::doubleValue).min().getAsDouble(); Double avgDistance = distanceList.stream().mapToDouble(Double::doubleValue).average().orElse(0.0D); Double maxDistance = distanceList.stream().mapToDouble(Double::doubleValue).max().getAsDouble(); return ImmutableTriple.of(minDistance, avgDistance, maxDistance); }

7. Conclusion

In this article, we've learned how to use arrays, collections, containers, and tuples to return multiple values from a method. We can use arrays and collections in simple cases since they wrap a single data type.

On the other hand, containers and tuples are useful in creating complex types, with containers offering better readability.

また、一部のサードパーティライブラリがペアタイプとトリプルタイプを実装していることを学び、Apache CommonsLangライブラリからいくつかの例を見ました。

いつものように、この記事のソースコードはGitHubから入手できます。