webentwicklung-frage-antwort-db.com.de

Wie schreibe ich eine Java-Funktion, die Werte mehrerer Datentypen zurückgibt?

Zum Beispiel möchte ich eine Funktion erstellen, die eine beliebige Zahl (negativ, null oder positiv) zurückgeben kann.

Aufgrund bestimmter Ausnahmen möchte ich jedoch, dass die Funktion BooleanFALSE zurückgibt.

Gibt es eine Möglichkeit, eine Funktion zu schreiben, die eine int oder eine Boolean zurückgeben kann?


Ok, das hat viele Antworten erhalten. Ich verstehe, ich gehe einfach falsch an das Problem heran und ich sollte throw irgendeine Art von Ausnahme in der Methode. Um eine bessere Antwort zu erhalten, gebe ich Ihnen Beispielcode. Bitte mach keinen Spaß :)

public class Quad {

  public static void main (String[] args) {

    double a, b, c;

    a=1; b=-7; c=12;
    System.out.println("x = " + quadratic(a, b, c, 1));   // x = 4.0
    System.out.println("x = " + quadratic(a, b, c, -1));  // x = 3.0


    // "invalid" coefficients. Let's throw an exception here. How do we handle the exception?
    a=4; b=4; c=16;
    System.out.println("x = " + quadratic(a, b, c, 1));   // x = NaN
    System.out.println("x = " + quadratic(a, b, c, -1));  // x = NaN

  }

  public static double quadratic(double a, double b, double c, int polarity) {

    double x = b*b - 4*a*c;

    // When x < 0, Math.sqrt(x) retruns NaN
    if (x < 0) {
      /*
        throw exception!
        I understand this code can be adjusted to accommodate 
        imaginary numbers, but for the sake of this example,
        let's just have this function throw an exception and
        say the coefficients are invalid
      */
    }

    return (-b + Math.sqrt(x) * polarity) / (2*a);

  }

}
15
maček

Nein, das geht in Java nicht.

Sie könnten jedoch eine Object zurückgeben. Durch die Rückgabe eines Objekts können Sie technisch eine abgeleitete Klasse wie Java.lang.Integer oder Java.lang.Boolean zurückgeben. Ich denke jedoch nicht, dass es die beste Idee ist.

13

Sie könnten dies technisch tun:

public <T> T doWork()
{
   if(codition)
   {
      return (T) new Integer(1);
   }
   else
   {
      return (T) Boolean.FALSE;
   }
}

Dann würde dieser Code kompilieren:

int x = doWork(); // the condition evaluates to true
boolean test = doWork();

Es kann jedoch durchaus zu Laufzeitausnahmen kommen, wenn die Methode den falschen Typ zurückgibt. Sie müssen auch Objekte anstelle von Primitiven zurückgeben, da T in Java.lang.Object gelöscht wird. Dies bedeutet, dass der zurückgegebene Typ Object erweitern muss (d. H. Ein Objekt sein muss). Das obige Beispiel verwendet Autoboxing, um einen primitiven Rückgabetyp zu erzielen.

Ich würde diesen Ansatz sicherlich nicht empfehlen, da Sie die Verwendung der Ausnahmebehandlung im IMO bewerten müssen. In Ausnahmefällen können Sie Ausnahmen feststellen, wenn Sie mit dieser Ausnahme etwas tun können (z. B. wiederherstellen, persistieren, erneut versuchen usw.). Ausnahmen sind eine Ausnahme zum erwarteten Workflow, nicht Teil davon.

11
hisdrewness

nein. Sie können am besten eine Instanz einer Klasse zurückgeben, die alle Dinge behandelt, die Sie zurückgeben möchten.

so etwas wie 

public class ReturnObj {
   public bool yesno; // yes or no
   public int val; // for int values
   public String mode; // mode describing what you returned, which the caller will need to understand.
}

natürlich musst du mit den Namen spielen ....

Dies scheint auch ein Codegeruch zu sein. Möglicherweise können Sie die Notwendigkeit beseitigen, so etwas zu tun, indem Sie den gewünschten Pfad außerhalb Ihrer Funktion angeben und dann eine bestimmte Funktion aufrufen, um eine boolesche oder eine bestimmte Funktion zu erhalten, um ein int zu erhalten, abhängig von der Qualifikation. 

6
hvgotcodes

Schreiben Sie eine Funktion, die eine Object zurückgibt. Lassen Sie es entweder die Wrapperobjekte Boolean oder Integer zurückgeben. Verwenden Sie dann instanceof, um herauszufinden, welche Anwendung verwendet werden soll.

3
Alex Churchill

IEEE Floating Point

Die meisten Sprachen behandeln Ihr spezifisches Beispiel ohne Ausnahmen oder Vereinigungstypen, da der IEEE-Gleitkommawert eine Darstellung für NaN enthält. Verwenden Sie in Java Double.NaN:

public static double quadratic(double a, double b, double c, int polarity) {
    double x = b*b - 4*a*c;

    // When x < 0, Math.sqrt(x) retruns NaN
    if (x < 0) {
        return Double.NaN;
    }
    return (-b + Math.sqrt(x) * polarity) / (2*a);
}

Das ergibt Ihre exakte Ausgabe, die Sie wollten:

x = 4.0
x = 3.0
x = NaN
x = NaN

Ausnahmen

Ausnahmen bilden The Old Java Way zur Lösung ähnlicher Probleme:

public static double quadratic(double a, double b, double c, int polarity) {
    double x = b*b - 4*a*c;
    // When x < 0, Math.sqrt(x) returns NaN
    if (x < 0) {
        throw new Exception("NaN")
    }
    return (-b + Math.sqrt(x) * polarity) / (2*a);
}

Hier ist Ihr Client-Code für eine Ausnahme.

a=1; b=-7; c=12;

// x = 4.0
try {
    System.out.println("x = " + quadratic(a, b, c, 1));
} catch (Exception iae) {
    System.out.println("Oopsie: " + iae.getMessage());
}

// x = 3.0
try {
    System.out.println("x = " + quadratic(a, b, c, -1));
} catch (Exception iae) {
    System.out.println("Oopsie: " + iae.getMessage());
}

// "invalid" coefficients.
a=4; b=4; c=16;

// Oopsie: NaN
try {
    System.out.println("x = " + quadratic(a, b, c, 1));
} catch (Exception iae) {
    System.out.println("Oopsie: " + iae.getMessage());
}

// Oopsie: NaN
try {
    System.out.println("x = " + quadratic(a, b, c, -1));
} catch (Exception iae) {
    System.out.println("Oopsie: " + iae.getMessage());
}

Unionstypen

Um wirklich zusammenhängende Typen wirklich an eine oder von einer Methode zu übergeben oder zurückzugeben, möchten Sie Union-Typen, die von Java nicht wirklich unterstützt werden. Paguro bietet jedoch Union Types , die Sie in Java wie folgt verwenden können (mithilfe von Oder):

public static Or<Double,String> quadratic(double a, double b,
                                          double c, int polarity) {
    double x = b*b - 4*a*c;

    // When x < 0, Math.sqrt(x) retruns NaN
    if (x < 0) {
        return Or.bad("NaN");
    }
    return Or.good((-b + Math.sqrt(x) * polarity) / (2*a));
}

@Test public void testQuadradic() {
    double a, b, c;
    a=1; b=-7; c=12;

    // x = Good(4.0)
    System.out.println("x = " + quadratic(a, b, c, 1));

    // x = 3.0
    System.out.println(
            (String) quadratic(a, b, c, -1)
                    .match(good -> "x = " + good,
                           bad -> "Oopsie: " + bad));

    // "invalid" coefficients.
    a=4; b=4; c=16;

    // x = Bad("NaN")
    System.out.println("x = " + quadratic(a, b, c, 1));

    // Oopsie: NaN
    System.out.println(
            (String) quadratic(a, b, c, -1)
                    .match(good -> "x = " + good,
                           bad -> "Oopsie: " + bad));
}

Fazit

Verwenden Sie für Ihr spezifisches Beispiel einfach Floating Point. Für eine allgemeinere Lösung finde ich Vereinigungstypen nützlicher als Ausnahmen. Sie können Vereinigungstypen als Argumente für eine Methode verwenden, die zwei verschiedene Eingaben annehmen kann, die keine gemeinsame Schnittstelle oder einen gemeinsamen Vorfahren haben. Sie sind auch für die funktionale Programmierung freundlicher.

3
GlenPeterson

Nein, ein Rückverweis auf einen Kunden.

Sie können ein Antwortobjekt schreiben, das ein boolesches und ein int zusammenkapselt, und die Werte entsprechend Ihrer Laune einstellen.

Wenn ich ein Benutzer wäre, würde ich denken, dass Ihr Design verwirrend war.

1
duffymo

mein Lehrer hatte eine coole Idee für eine tryParse C # -ähnliche Methode in Java. Ich hoffe, es hilft

import Java.util.Scanner;

public class Program {
    static Scanner scanner = new Scanner(System.in);
    public static void main(String[] args) {
        System.out.println("Enter number");
        String input = scanner.next();
        int[] num ={0};
        if(tryParse(input,num))
            System.out.println(num[0] * num[0]);
    }
    static boolean tryParse(String inputString,int[] outputInt){
        try{
            outputInt[0] = Integer.parseInt(inputString);
            return true;
        }catch(Exception e){
            return false;
        }
    }
}
1
Munchyzzz

Dies ist möglicherweise nicht die beste Lösung, je nachdem, was Sie tun möchten. Es ist jedoch eine einfache Möglichkeit, das Problem zu lösen, indem die Funktion ein int oder eine Konstante außerhalb des möglichen Bereichs (z. B. RETURNED_FALSE/TRUE) zurückgibt und dies überprüft .

0
EscapeNT