Bagaimana cara mengembalikan 2 nilai dari metode Java?


179

Saya mencoba mengembalikan 2 nilai dari metode Java tapi saya mendapatkan kesalahan ini. Ini kode saya:

// Method code
public static int something(){
    int number1 = 1;
    int number2 = 2;

    return number1, number2;
}

// Main method code
public static void main(String[] args) {
    something();
    System.out.println(number1 + number2);
}

Kesalahan:

Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - missing return statement
    at assignment.Main.something(Main.java:86)
    at assignment.Main.main(Main.java:53)

Hasil Jawa: 1


1
Haruskah duplikat itu berputar sebaliknya? Jawabannya di sini sepertinya lebih baik.
J Richard Snape

Jawaban:


239

Alih-alih mengembalikan array yang berisi dua nilai atau menggunakan Pairkelas generik , pertimbangkan membuat kelas yang mewakili hasil yang ingin Anda kembalikan, dan kembalikan instance kelas itu. Beri kelas nama yang bermakna. Manfaat dari pendekatan ini dibandingkan menggunakan array adalah keamanan tipe dan itu akan membuat program Anda lebih mudah dimengerti.

Catatan: Kelas generik Pair, seperti yang diusulkan dalam beberapa jawaban lain di sini, juga memberi Anda keamanan mengetik, tetapi tidak memberikan hasil yang diwakilinya.

Contoh (yang tidak menggunakan nama yang benar-benar bermakna):

final class MyResult {
    private final int first;
    private final int second;

    public MyResult(int first, int second) {
        this.first = first;
        this.second = second;
    }

    public int getFirst() {
        return first;
    }

    public int getSecond() {
        return second;
    }
}

// ...

public static MyResult something() {
    int number1 = 1;
    int number2 = 2;

    return new MyResult(number1, number2);
}

public static void main(String[] args) {
    MyResult result = something();
    System.out.println(result.getFirst() + result.getSecond());
}

1
Ini akan menjadi rute pilihan saya - mungkin pasangan angka memiliki beberapa makna, dan alangkah baiknya jika tipe pengembalian mewakili ini.
Armand

3
Anda dapat menggunakan SimpleEntry <type_of_value_1, type_of_value_2> dari java.util.AbstractMap.SimpleEntry dan menggunakannya dengan getKey () untuk mendapatkan objek 1 dan getValue () untuk mendapatkan objek 2
Crystalonics

45
Saya merasa sangat kuat bahwa Java harus memungkinkan Anda mengembalikan beberapa nilai. Itu akan lebih cepat (lebih sedikit objek yang dibuat) dan tidak akan memerlukan kelas tambahan (kode kembung) setiap kali Anda ingin melakukan sesuatu yang sedikit berbeda. Saya tidak melihat kelemahan, mungkin seseorang dapat mencerahkan saya?
Chris Seline

Ini hanya solusi untuk pertanyaan yang diajukan, yang masih berdiri "bagaimana mengembalikan 2 nilai dari metode seperti yang kita lakukan dengan Python".
Anum Sheraz

4
@AnumSheraz Jawaban untuk "bagaimana ... persis seperti di Python" adalah: Anda tidak, karena Java tidak memiliki fitur bahasa seperti itu ...
Jesper

73

Java tidak mendukung pengembalian multi-nilai. Kembalikan array nilai.

// Function code
public static int[] something(){
    int number1 = 1;
    int number2 = 2;
    return new int[] {number1, number2};
}

// Main class code
public static void main(String[] args) {
  int result[] = something();
  System.out.println(result[0] + result[1]);
}

7
Ini hampir selalu hal yang salah untuk dilakukan, terutama jika jenis dari kedua nilai hasil berbeda.
Kevin Sitze

7
@BarAkiva, alasannya salah adalah karena Anda kehilangan keamanan jenis. Jika Anda mengembalikan nilai tipe yang homogen maka Anda harus selalu lebih memilih Daftar daripada array. Khususnya, jika Anda berurusan dengan nilai generik maka Daftar <T> selalu lebih disukai sebagai nilai balik di atas T [] karena Anda selalu dapat membuat Daftar pada tipe generik tetapi tidak pernah array; Anda tidak dapat melakukan ini: "T baru [panjang];" Pendekatan menciptakan kelas Pair seperti yang ditunjukkan di sini untuk tipe yang berbeda adalah pilihan yang lebih baik untuk tipe yang heterogen.
Kevin Sitze

41

Anda bisa menerapkan generik Pairjika Anda yakin bahwa Anda hanya perlu mengembalikan dua nilai:

public class Pair<U, V> {

 /**
     * The first element of this <code>Pair</code>
     */
    private U first;

    /**
     * The second element of this <code>Pair</code>
     */
    private V second;

    /**
     * Constructs a new <code>Pair</code> with the given values.
     * 
     * @param first  the first element
     * @param second the second element
     */
    public Pair(U first, V second) {

        this.first = first;
        this.second = second;
    }

//getter for first and second

dan kemudian minta kembali metode itu Pair:

public Pair<Object, Object> getSomePair();

Seperti apa kembalinya metode ini?
Jwan622

Sesuatu di sepanjang baris: pair = Pair baru (thing1, thing2) .... return pair;
Lars Andren

27

Anda hanya dapat mengembalikan satu nilai di Java, jadi cara yang paling rapi adalah seperti ini:

return new Pair<Integer>(number1, number2);

Ini versi terbaru dari kode Anda:

public class Scratch
{
    // Function code
    public static Pair<Integer> something() {
        int number1 = 1;
        int number2 = 2;
        return new Pair<Integer>(number1, number2);
    }

    // Main class code
    public static void main(String[] args) {
        Pair<Integer> pair = something();
        System.out.println(pair.first() + pair.second());
    }
}

class Pair<T> {
    private final T m_first;
    private final T m_second;

    public Pair(T first, T second) {
        m_first = first;
        m_second = second;
    }

    public T first() {
        return m_first;
    }

    public T second() {
        return m_second;
    }
}

8

Inilah solusi yang sangat sederhana dan singkat dengan SimpleEntry:

AbstractMap.Entry<String, Float> myTwoCents=new AbstractMap.SimpleEntry<>("maximum possible performance reached" , 99.9f);

String question=myTwoCents.getKey();
Float answer=myTwoCents.getValue();

Hanya menggunakan Java built-in functions dan ia datang dengan manfaat jenis keselamatan.


6

Anda harus menggunakan koleksi untuk mengembalikan lebih dari satu nilai pengembalian

dalam kasus Anda, Anda menulis kode Anda sebagai

public static List something(){
        List<Integer> list = new ArrayList<Integer>();
        int number1 = 1;
        int number2 = 2;
        list.add(number1);
        list.add(number2);
        return list;
    }

    // Main class code
    public static void main(String[] args) {
      something();
      List<Integer> numList = something();
    }

4
public class Mulretun
{
    public String name;;
    public String location;
    public String[] getExample()
    {
        String ar[] = new String[2];
        ar[0]="siva";
        ar[1]="dallas";
        return ar; //returning two values at once
    }
    public static void main(String[] args)
    {
        Mulretun m=new Mulretun();
        String ar[] =m.getExample();
        int i;
        for(i=0;i<ar.length;i++)
        System.out.println("return values are: " + ar[i]);      

    }
}

o/p:
return values are: siva
return values are: dallas

4

Gunakan objek jenis Pair / Tuple, Anda bahkan tidak perlu membuatnya jika Anda bergantung pada Apache commons-lang. Cukup gunakan kelas Pair .


Mengapa ini tidak lebih dipilih?
Rauni Lillemets

3

Saya ingin tahu mengapa tidak ada yang datang dengan solusi panggilan balik yang lebih elegan. Jadi, alih-alih menggunakan tipe pengembalian Anda menggunakan handler yang diteruskan ke metode sebagai argumen. Contoh di bawah ini memiliki dua pendekatan yang berbeda. Saya tahu yang mana dari keduanya yang lebih anggun bagi saya. :-)

public class DiceExample {

    public interface Pair<T1, T2> {
        T1 getLeft();

        T2 getRight();
    }

    private Pair<Integer, Integer> rollDiceWithReturnType() {

        double dice1 = (Math.random() * 6);
        double dice2 = (Math.random() * 6);

        return new Pair<Integer, Integer>() {
            @Override
            public Integer getLeft() {
                return (int) Math.ceil(dice1);
            }

            @Override
            public Integer getRight() {
                return (int) Math.ceil(dice2);
            }
        };
    }

    @FunctionalInterface
    public interface ResultHandler {
        void handleDice(int ceil, int ceil2);
    }

    private void rollDiceWithResultHandler(ResultHandler resultHandler) {
        double dice1 = (Math.random() * 6);
        double dice2 = (Math.random() * 6);

        resultHandler.handleDice((int) Math.ceil(dice1), (int) Math.ceil(dice2));
    }

    public static void main(String[] args) {

        DiceExample object = new DiceExample();


        Pair<Integer, Integer> result = object.rollDiceWithReturnType();
        System.out.println("Dice 1: " + result.getLeft());
        System.out.println("Dice 2: " + result.getRight());

        object.rollDiceWithResultHandler((dice1, dice2) -> {
            System.out.println("Dice 1: " + dice1);
            System.out.println("Dice 2: " + dice2);
        });
    }
}

2

Anda tidak perlu membuat kelas Anda sendiri untuk mengembalikan dua nilai yang berbeda. Cukup gunakan HashMap seperti ini:

private HashMap<Toy, GameLevel> getToyAndLevelOfSpatial(Spatial spatial)
{
    Toy toyWithSpatial = firstValue;
    GameLevel levelToyFound = secondValue;

    HashMap<Toy,GameLevel> hm=new HashMap<>();
    hm.put(toyWithSpatial, levelToyFound);
    return hm;
}

private void findStuff()
{
    HashMap<Toy, GameLevel> hm = getToyAndLevelOfSpatial(spatial);
    Toy firstValue = hm.keySet().iterator().next();
    GameLevel secondValue = hm.get(firstValue);
}

Anda bahkan mendapatkan manfaat dari keamanan tipe.


2
Anda bahkan tidak memerlukan HashMap, cukup gunakan SimpleEntry!
Xerus

Mengapa HashMap, boleh saya tanyakan? Itu tampak seperti struktur data yang aneh untuk digunakan di sini.
Neil Chowdhury

@Neil Chowdhury Tidak ada alasan lain selain karena itu adalah Kelas bawaan yang memiliki dua parameter yang dapat ditentukan. Seperti yang ditunjukkan Xerus, AbstractMap.SimpleEntry adalah pilihan yang lebih ringan di sini. Silakan lihat jawaban yang sesuai di bawah ini!
Kode ninetyninepointnine

2

Menurut pendapat saya yang terbaik adalah membuat kelas baru yang konstruktor adalah fungsi yang Anda butuhkan, misalnya:

public class pairReturn{
        //name your parameters:
        public int sth1;
        public double sth2;
        public pairReturn(int param){
            //place the code of your function, e.g.:
            sth1=param*5;
            sth2=param*10;
        }
    }

Kemudian cukup gunakan konstruktor karena Anda akan menggunakan fungsi:

pairReturn pR = new pairReturn(15);

dan Anda dapat menggunakan pR.sth1, pR.sth2 sebagai "2 hasil dari fungsi"


1

Anda juga dapat mengirim objek yang bisa berubah sebagai parameter, jika Anda menggunakan metode untuk memodifikasinya, mereka akan dimodifikasi ketika Anda kembali dari fungsi. Itu tidak akan bekerja pada hal-hal seperti Float, karena tidak dapat diubah.

public class HelloWorld{

     public static void main(String []args){
        HelloWorld world = new HelloWorld();

        world.run();
     }



    private class Dog
    {
       private String name;
       public void setName(String s)
       {
           name = s;
       }
       public String getName() { return name;}
       public Dog(String name)
       {
           setName(name);
       }
    }

    public void run()
    {
       Dog newDog = new Dog("John");
       nameThatDog(newDog);
       System.out.println(newDog.getName());
     }


     public void nameThatDog(Dog dog)
     {
         dog.setName("Rutger");
     }
}

Hasilnya adalah: Rutger


1

Kembalikan Array Objek

private static Object[] f () 
{ 
     double x =1.0;  
     int y= 2 ;
     return new Object[]{Double.valueOf(x),Integer.valueOf(y)};  
}

0

Pertama, akan lebih baik jika Java memiliki tuple untuk mengembalikan beberapa nilai.

Kedua, kode sesederhana mungkin Pair kelas , atau gunakan array.

Tapi, jika Anda lakukan perlu untuk kembali sepasang, mempertimbangkan apa konsep yang diwakilinya (dimulai dengan nama field, maka nama kelas) - dan apakah itu memainkan peran yang lebih besar daripada yang Anda pikir, dan jika itu akan membantu desain Anda secara keseluruhan memiliki abstraksi eksplisit untuk itu. Mungkin itu code hint...
Tolong Catatan: Saya tidak dogmatis mengatakan itu akan membantu, tetapi hanya untuk melihat, untuk melihat apakah itu ... atau jika tidak.


-7

dan ini adalah bagaimana Anda melakukannya dalam JS: return { objA, valueB }. Saya tahu ini offtopic, tapi saya tidak bisa meninggalkan komentar ini setelah melihat bagaimana seluruh kelas baru harus diimplementasikan di Jawa. JavaScript - berhenti menyia-nyiakan hidup Anda dan mulai Scripting!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.