Bagaimana Mengembalikan Banyak Nilai Dari Metode Java

1. Ikhtisar

Dalam tutorial ini, kita akan mempelajari berbagai cara untuk mengembalikan banyak nilai dari metode Java.

Pertama, kami akan mengembalikan array dan koleksi. Kemudian, kami akan menunjukkan cara menggunakan kelas kontainer untuk data kompleks dan mempelajari cara membuat kelas tuple generik.

Terakhir, kita akan melihat contoh bagaimana menggunakan pustaka pihak ketiga untuk mengembalikan beberapa nilai.

2. Menggunakan Array

Array dapat digunakan untuk mengembalikan tipe data primitif dan referensi .

Misalnya, metode getCoordinates berikut mengembalikan larik dua nilai ganda :

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

Jika kita ingin mengembalikan array dengan tipe referensi berbeda, kita bisa menggunakan tipe induk umum sebagai tipe array :

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

Di sini kita telah mendefinisikan array koordinat tipe Number karena ini adalah kelas umum antara elemen Integer dan Double .

3. Menggunakan Koleksi

Dengan koleksi Java generik, kita bisa mengembalikan beberapa nilai dari tipe yang sama .

Kerangka koleksi memiliki spektrum kelas dan antarmuka yang luas. Namun, di bagian ini, kita akan membatasi diskusi kita pada antarmuka Daftar dan Peta .

3.1. Mengembalikan Nilai dari Jenis Serupa dalam Daftar

Untuk memulai, mari kita tulis ulang contoh array sebelumnya menggunakan List :

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

Seperti Angka [] , koleksi List menyimpan urutan elemen tipe campuran yang semuanya berjenis sama.

3.2. Mengembalikan Nilai Bernama di Peta

Jika kami ingin memberi nama setiap entri dalam koleksi kami, Peta dapat digunakan sebagai gantinya:

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

Pengguna metode getCoordinatesMap bisa menggunakan kunci " longitude" atau " latitude" dengan metode Map # get untuk mengambil nilai yang sesuai.

4. Menggunakan Kelas Kontainer

Tidak seperti array dan koleksi, kelas kontainer (POJO) dapat menggabungkan beberapa bidang dengan tipe data yang berbeda .

Misalnya, kelas Koordinat berikut memiliki dua tipe data yang berbeda, ganda dan String :

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 }

Menggunakan kelas kontainer seperti Koordinat memungkinkan kita untuk membuat model tipe data kompleks dengan nama yang bermakna .

Langkah selanjutnya adalah membuat instance dan mengembalikan instance Koordinat :

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

Kami harus mencatat bahwa kami merekomendasikan agar kami membuat kelas data seperti Koordinat tidak dapat diubah . Dengan demikian, kami membuat objek yang sederhana, aman untuk thread, dan dapat dibagikan.

5. Menggunakan Tuple

Seperti wadah, tupel menyimpan bidang dari berbagai jenis. Namun, keduanya berbeda karena tidak spesifik untuk aplikasi .

Mereka terspesialisasi ketika kita menggunakannya untuk mendeskripsikan tipe mana yang kita ingin mereka tangani, tetapi merupakan wadah tujuan umum dari sejumlah nilai. Ini berarti kita tidak perlu menulis kode khusus untuk memilikinya, dan kita dapat menggunakan perpustakaan, atau membuat implementasi tunggal yang umum.

Sebuah tupel dapat terdiri dari sejumlah field dan sering disebut Tuple n, dimana n adalah jumlah field. Misalnya, Tuple2 adalah tupel dua bidang, Tuple3 adalah tupel tiga bidang, dan seterusnya.

Untuk mendemonstrasikan pentingnya tupel, mari pertimbangkan contoh berikut. Misalkan kita ingin mencari jarak antara titik Koordinat dan semua titik lain di dalam Daftar . Kemudian, kita perlu mengembalikan objek Koordinat terjauh itu, beserta jaraknya.

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.

Kami juga mengetahui bahwa beberapa pustaka pihak ketiga telah menerapkan tipe berpasangan dan tiga dan melihat beberapa contoh dari pustaka Apache Commons Lang.

Seperti biasa, kode sumber untuk artikel ini tersedia di GitHub.