Java yönteminden 2 değer nasıl döndürülür?


179

Bir Java yönteminden 2 değer döndürmeye çalışıyorum ama bu hataları alıyorum. İşte benim kod:

// 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);
}

Hata:

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)

Java Sonucu: 1


1
Bu kopya başka bir yoldan gitmeli mi? Bu sorunun cevabı daha iyi görünüyor.
J Richard Snape

Yanıtlar:


240

İki değeri içeren bir dizi döndürmek veya genel bir Pairsınıf kullanmak yerine, döndürmek istediğiniz sonucu temsil eden bir sınıf oluşturmayı ve o sınıfın bir örneğini döndürmeyi düşünün. Sınıfa anlamlı bir ad verin. Bu yaklaşımın bir dizi kullanmanın faydaları tür güvenliğidir ve programınızın daha kolay anlaşılmasını sağlayacaktır.

Not: PairBuradaki diğer cevapların bazılarında önerildiği gibi genel bir sınıf da size güvenlik sağlar, ancak sonucun temsil ettiği şeyi iletmez.

Örnek (gerçekten anlamlı isimler kullanmaz):

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
Bu benim tercih ettiğim rota olurdu - muhtemelen sayı çiftinin bir anlamı var ve dönüş türünün bunu temsil etmesi güzel olurdu.
Armand

3
Sen nesne 1 ve getValue () nesneyi 2 almak için java.util.AbstractMap.SimpleEntry dan SimpleEntry <type_of_value_1, type_of_value_2> kullanmak ve almak için Getkey () ile birlikte kullanabilirsiniz
Crystalonics

45
Java'nın birden fazla değer döndürmenize izin vermesi gerektiğini çok güçlü hissediyorum. Her zaman biraz farklı bir şey yapmak istediğinizde daha hızlı (daha az nesne oluşturulur) ve ekstra sınıflar (şişirilmiş kod) gerektirmez. Hiç dezavantajı görmüyorum, belki biri beni aydınlatabilir mi?
Chris Seline

Bu sadece "Python'da yaptığımız gibi yöntemden 2 değerin nasıl döndürüleceği" anlamına gelen, sorulan soru için bir çözümdür.
Anum Sheraz

4
@AnumSheraz "Nasıl ... Python'da olduğu gibi" cevabı şöyledir: Java'nın böyle bir dil özelliği yoktur ...
Jesper

73

Java, çok değerli dönüşleri desteklemez. Bir değer dizisi döndürür.

// 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
Bu, özellikle iki sonuç değerinin türleri farklıysa, hemen hemen her zaman yapılacak yanlış şeydir.
Kevin Sitze

7
@BarAkiva, yanlış olmasının nedeni, gevşek tip güvenliğiniz. Homojen tipte değerler döndürüyorsanız, her zaman bir dizi yerine bir Liste tercih etmelisiniz. Özellikle, genel değerlerle uğraşıyorsanız, bir List <T> her zaman T [] yerine bir dönüş değeri olarak tercih edilir, çünkü her zaman genel bir türde bir Liste oluşturabilirsiniz, ancak asla bir dizi oluşturmazsınız; bunu yapamazsınız: "yeni T [uzunluk];" Farklı türler için burada belirtildiği gibi bir Pair sınıfı yaratma yaklaşımı heterojen türler için daha iyi bir seçenektir.
Kevin Sitze

41

Yalnızca Pairiki değer döndürmeniz gerektiğinden eminseniz genel bir uygulayabilirsiniz :

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

ve sonra yöntemin bunu döndürmesini sağlayın Pair:

public Pair<Object, Object> getSomePair();

Bu yöntemin geri dönüşü nasıl olurdu?
Jwan622

Çizgileri boyunca bir şey: pair = new Pair (thing1, thing2) .... dönüş çifti;
Lars Andren

27

Java'da yalnızca bir değer döndürebilirsiniz, bu yüzden en güzel yol aşağıdaki gibidir:

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

Kodunuzun güncellenmiş bir sürümü:

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

İşte SimpleEntry ile gerçekten basit ve kısa bir çözüm:

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

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

Yalnızca Java yerleşik işlevlerini kullanır ve güvenlik avantajı ile birlikte gelir.


6

birden fazla dönüş değeri döndürmek için koleksiyonları kullanmanız gerekir

sizin durumunuzda kodunuzu

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

Bir Pair / Tuple tipi nesne kullanın, u Apache commons-lang'ye bağlıysanız bir tane oluşturmanız bile gerekmez. Yalnızca Pair sınıfını kullanın .


Bu neden daha fazla oylanmıyor?
Rauni Lillemets

3

Kimsenin neden daha zarif geri arama çözümü bulamadığını merak ediyorum. Bu nedenle, bir dönüş türü kullanmak yerine, yönteme bağımsız değişken olarak iletilen bir işleyici kullanırsınız. Aşağıdaki örnek iki zıt yaklaşıma sahiptir. İkisinden hangisinin benim için daha zarif olduğunu biliyorum. :-)

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

İki farklı değer döndürmek için kendi sınıfınızı oluşturmanız gerekmez. Bunun gibi bir HashMap kullanın:

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);
}

Hatta tip güvenliği avantajına sahipsiniz.


2
Bir HashMap'e bile ihtiyacınız yok, sadece bir SimpleEntry kullanın!
Xerus

Neden bir HashMap isteyebilirim? Burada kullanmak garip bir veri yapısı gibi görünüyor.
Neil Chowdhury

@Neil Chowdhury İki tanımlanabilir parametre alan, uygun bir şekilde yerleşik bir Sınıf olmasından başka bir sebep yok. Xerus'un belirttiği gibi, AbstractMap.SimpleEntry burada daha hafif bir seçenektir. Lütfen aşağıdaki ilgili cevaba bakınız!
Kod ninetyninepointnine

2

Bence en iyisi, hangi yapıcı ihtiyacınız olan işlev olan yeni bir sınıf oluşturmaktır, örneğin:

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;
        }
    }

Ardından, yapıcıyı işlevi kullandığınız gibi kullanın:

pairReturn pR = new pairReturn(15);

pR.sth1, pR.sth2 komutunu "işlevin 2 sonucu" olarak kullanabilirsiniz


1

Değiştirilebilir nesneleri parametre olarak da gönderebilirsiniz, eğer bunları değiştirmek için yöntemler kullanırsanız, işlevden döndüğünüzde bunlar değiştirilecektir. Değişmez olduğu için Float gibi şeyler üzerinde çalışmaz.

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");
     }
}

Sonuç: Rutger


1

Nesneler Dizisi Döndürme

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

0

İlk olarak, Java'da birden fazla değer döndürmek için tuples olsaydı daha iyi olurdu.

İkinci olarak, mümkün olan en basit Pairsınıfı kodlayın veya bir dizi kullanın.

Eğer Ama eğer bunu bir çift dönmek gereğini, (daha sonra sınıf adı, onun alan adları ile başlayan) neyi temsil ettiği kavram düşünün - ve düşündüğünden daha büyük bir rol oynayıp oynamadığını ve bu yardımcı olacağını eğer genel tasarımı bir olması bunun için açık soyutlama. Belki de code hint...
Lütfen Dikkat: Dogmatik olarak bunun yardımcı olacağını söylemiyorum , sadece bakmak, işe yarayıp yaramadığını görmek ... ya da değil.


-7

ve bu JS böyle yaparız: return { objA, valueB }. Oftopik olduğunu biliyorum, ancak Java'da tamamen yeni bir sınıfın nasıl uygulanması gerektiğini gördükten sonra bu yorumu bırakmaktan kaçınamıyorum. JavaScript - hayatınızı boşa harcamayı bırakın ve Scripting'e başlayın!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.