Ich möchte zwei Objekte von einer Java-Methode zurückgeben und habe mich gefragt, was ein guter Weg sein könnte, dies zu tun.
Die möglichen Möglichkeiten, die ich mir vorstellen kann, sind: Rückgabe eines HashMap
(da die beiden Objekte miteinander verbunden sind) oder Rückgabe eines ArrayList
von Object
Objekten.
Genauer gesagt sind die beiden Objekte, die ich zurückgeben möchte, (a) List
Objekte und (b) durch Kommas getrennte Namen derselben.
Ich möchte diese beiden Objekte von einer Methode zurückgeben, da ich die Liste der Objekte nicht durchlaufen möchte, um die durch Kommas getrennten Namen zu erhalten (was ich in dieser Methode in derselben Schleife tun kann).
Irgendwie HashMap
sieht die Rückgabe von a nicht sehr elegant aus.
List
Referenz und eine Art Nachschlagetabelle haben.Antworten:
Wenn Sie zwei Objekte zurückgeben möchten, möchten Sie normalerweise ein einzelnes Objekt zurückgeben, das stattdessen die beiden Objekte kapselt.
Sie können eine Liste von
NamedObject
Objekten wie folgt zurückgeben:Dann können Sie einfach a zurückgeben
List<NamedObject<WhateverTypeYouWant>>
.Außerdem: Warum sollten Sie eine durch Kommas getrennte Liste von Namen anstelle von a zurückgeben
List<String>
? Oder noch besser, geben Sie a zurück,Map<String,TheObjectType>
wobei die Schlüssel die Namen und Werte der Objekte sind (es sei denn, Ihre Objekte haben eine bestimmte Reihenfolge angegeben. In diesem FallNavigableMap
könnte a das sein, was Sie möchten.quelle
Wenn Sie wissen, dass Sie zwei Objekte zurückgeben werden, können Sie auch ein generisches Paar verwenden:
Bearbeiten Eine vollständigere Implementierung der oben genannten:
Anmerkungen, hauptsächlich zu Rost mit Java & Generika:
a
undb
sind unveränderlich.makePair
Die statische Methode hilft Ihnen bei der Eingabe von Kesselplatten, was der Diamantoperator in Java 7 weniger nervig macht. Es gibt einige Arbeiten, um dieses wirklich schöne Re: Generikum zu machen, aber es sollte jetzt in Ordnung sein. (vgl. PECS)hashcode
undequals
werden durch Sonnenfinsternis erzeugt.cast
Methode ist in Ordnung, scheint aber nicht ganz richtig zu sein.isInstance
notwendig sind.quelle
Pair
Implementierung. Eine kleine Änderung, die ich vornehmen würde: Fügen Sie dem eine Nachricht hinzuClassCastException
. Andernfalls wird das Debuggen zum Albtraum, wenn dies aus irgendeinem Grund fehlschlägt. (und die Rohtypen-Unterdrückungswarnungen wären unnötig, wenn Sie sie umwandeln würdenPair<?,?>
(was funktioniert, weil Sie nurObject
Methoden vona
und benötigenb
). Stört es Sie, wenn ich den Code optimiere?Versuchen Sie es, falls die von Ihnen aufgerufene Methode privat ist oder von einem Ort aus aufgerufen wird
Der Anrufer sieht aus wie:
Das Pair-Beispiel von David Hanak hat keinen syntaktischen Vorteil und ist auf zwei Werte beschränkt.
Und der Anrufer sieht aus wie:
quelle
Pair<T1, T2>
,Tuple<T1, T2, T3>
,Tuple<T1, T2, T3, T4>
Usw. Dann eine spezifische Verwendung zeigt die Anzahl und Arten von ParameternPair<int, String> temp = ...
oder was auch immer.Sie können eine der folgenden Möglichkeiten verwenden:
1) Array verwenden
2) Verwenden von ArrayList
3) Verwenden von HashMap
4) Verwenden Ihrer benutzerdefinierten Containerklasse
5) Verwenden von AbstractMap.simpleEntry
6) Mit Pair von Apache Commons
quelle
Ich definiere fast immer n-Tupel-Klassen, wenn ich in Java codiere. Zum Beispiel:
Ich weiß, dass es ein bisschen hässlich ist, aber es funktioniert und Sie müssen Ihre Tupeltypen nur einmal definieren. Tupel fehlen Java wirklich.
BEARBEITEN: Das Beispiel von David Hanak ist eleganter, da es die Definition von Gettern vermeidet und das Objekt dennoch unveränderlich hält.
quelle
Vor Java 5 würde ich zustimmen, dass die Map-Lösung nicht ideal ist. Sie können den Typ der Kompilierungszeit nicht überprüfen, sodass zur Laufzeit Probleme auftreten können. Mit Java 5 haben wir jedoch generische Typen.
Ihre Methode könnte also so aussehen:
MyType ist natürlich der Objekttyp, den Sie zurückgeben.
Grundsätzlich denke ich, dass die Rückgabe einer Map in diesem Fall die richtige Lösung ist, da Sie genau das zurückgeben möchten - eine Zuordnung einer Zeichenfolge zu einem Objekt.
quelle
Alternativ verwende ich in Situationen, in denen ich eine Reihe von Dingen von einer Methode zurückgeben möchte, manchmal einen Rückrufmechanismus anstelle eines Containers. Dies funktioniert sehr gut in Situationen, in denen ich nicht im Voraus angeben kann, wie viele Objekte generiert werden sollen.
Bei Ihrem speziellen Problem würde es ungefähr so aussehen:
quelle
java
, wenn Sie bezweckenA
Anruf - ObjektB.getResult()
undB.getResult()
AnrufeA.finishResult()
als eincallback
, wird das ObjektB
get Müll gesammelt oder es bis A endet nicht bleiben um ?? wahrscheinlich eine dumme Frage, aber es ist eine grundlegende Verwirrung, die ich habe!Apache Commons hat dafür Tupel und Triple:
ImmutablePair<L,R>
Ein unveränderliches Paar, das aus zwei Objektelementen besteht.ImmutableTriple<L,M,R>
Ein unveränderliches Tripel bestehend aus drei Objektelementen.MutablePair<L,R>
Ein veränderliches Paar, das aus zwei Objektelementen besteht.MutableTriple<L,M,R>
Ein veränderliches Tripel, bestehend aus drei Objektelementen.Pair<L,R>
Ein Paar bestehend aus zwei Elementen.Triple<L,M,R>
Ein Triple bestehend aus drei Elementen.Quelle: https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html
quelle
Während in Ihrem Fall der Kommentar ein guter Weg sein kann, können Sie ihn in Android verwenden
Pair
. Einfachquelle
Verwendung des folgenden Eingabeobjekts Beispiel:
quelle
In Bezug auf das Problem mit mehreren Rückgabewerten im Allgemeinen verwende ich normalerweise eine kleine Hilfsklasse, die einen einzelnen Rückgabewert umschließt und als Parameter an die Methode übergeben wird:
(Für primitive Datentypen verwende ich geringfügige Variationen, um den Wert direkt zu speichern.)
Eine Methode, die mehrere Werte zurückgeben möchte, wird dann wie folgt deklariert:
Möglicherweise besteht der Hauptnachteil darin, dass der Aufrufer die Rückgabeobjekte im Voraus vorbereiten muss, falls er sie verwenden möchte (und die Methode sollte nach Nullzeigern suchen).
Vorteile (im Vergleich zu anderen vorgeschlagenen Lösungen):
quelle
Alle möglichen Lösungen sind ein Kludge (wie Containerobjekte, Ihre HashMap-Idee, "mehrere Rückgabewerte", wie sie über Arrays realisiert werden). Ich empfehle, die durch Kommas getrennte Liste aus der zurückgegebenen Liste neu zu generieren. Der Code wird am Ende viel sauberer.
quelle
Halten Sie es einfach und erstellen Sie eine Klasse für Situationen mit mehreren Ergebnissen. In diesem Beispiel werden eine ArrayList und ein Nachrichtentext von einem Datenbankhelper getInfo akzeptiert.
Wo Sie die Routine aufrufen, die mehrere Werte zurückgibt, die Sie codieren:
In der Routine getInfo codieren Sie:
und definieren Sie eine Klasse multResult mit:
}}
quelle
Aus meiner Sicht gibt es hier wirklich drei Möglichkeiten, und die Lösung hängt vom Kontext ab. Sie können die Konstruktion des Namens in der Methode implementieren, mit der die Liste erstellt wird. Dies ist die Wahl, die Sie gewählt haben, aber ich denke nicht, dass es die beste ist. Sie erstellen eine Kopplung in der Producer-Methode mit der Consuming-Methode, die nicht vorhanden sein muss. Andere Anrufer benötigen möglicherweise keine zusätzlichen Informationen, und Sie würden zusätzliche Informationen für diese Anrufer berechnen.
Alternativ können Sie die aufrufende Methode den Namen berechnen lassen. Wenn nur ein Anrufer diese Informationen benötigt, können Sie dort anhalten. Sie haben keine zusätzlichen Abhängigkeiten, und obwohl ein wenig zusätzliche Berechnung erforderlich ist, haben Sie vermieden, Ihre Konstruktionsmethode zu spezifisch zu gestalten. Dies ist ein guter Kompromiss.
Schließlich könnte die Liste selbst für die Erstellung des Namens verantwortlich sein. Dies ist der Weg, den ich gehen würde, wenn die Berechnung von mehr als einem Anrufer durchgeführt werden muss. Ich denke, dies überträgt die Verantwortung für die Erstellung der Namen mit der Klasse, die am engsten mit den Objekten selbst verwandt ist.
Im letzteren Fall würde meine Lösung darin bestehen, eine spezielle List-Klasse zu erstellen, die eine durch Kommas getrennte Zeichenfolge der Namen der darin enthaltenen Objekte zurückgibt. Machen Sie die Klasse so intelligent, dass sie die Namenszeichenfolge im laufenden Betrieb erstellt, wenn Objekte hinzugefügt und daraus entfernt werden. Geben Sie dann eine Instanz dieser Liste zurück und rufen Sie die Namensgenerierungsmethode nach Bedarf auf. Obwohl es fast genauso effizient (und einfacher) sein kann, die Berechnung der Namen einfach bis zum ersten Aufruf der Methode zu verzögern und dann zu speichern (verzögertes Laden). Wenn Sie ein Objekt hinzufügen / entfernen, müssen Sie nur den berechneten Wert entfernen und ihn beim nächsten Aufruf neu berechnen lassen.
quelle
Kann so etwas wie ein Tupel in dynamischer Sprache (Python)
und so verwenden
quelle
Ich verfolgte einen ähnlichen Ansatz wie in den anderen Antworten beschrieben mit ein paar Änderungen, basierend auf der Anforderung, die ich hatte. Im Grunde habe ich die folgenden Klassen erstellt (Nur für den Fall, dass alles Java ist):
Dann war meine Anforderung einfach: In der Repository-Klasse, die die Datenbank erreicht, muss ich für die Get-Methoden, um Daten aus der Datenbank abzurufen, prüfen, ob sie fehlgeschlagen sind oder erfolgreich sind. Wenn dies erfolgreich ist, muss ich mit der Rückgabeliste spielen Wenn dies fehlschlägt, stoppen Sie die Ausführung und benachrichtigen Sie den Fehler.
So sind meine Methoden zum Beispiel wie folgt:
Wobei ResultMessage nur eine Klasse mit zwei Feldern (Code / Nachricht) ist und Customer eine Klasse mit einer Reihe von Feldern ist, die aus der Datenbank stammen.
Um das Ergebnis zu überprüfen, mache ich einfach Folgendes:
quelle
In C ++ (STL) gibt es eine Paarklasse zum Bündeln von zwei Objekten. In Java Generics ist keine Paarklasse verfügbar, obwohl eine gewisse Nachfrage besteht danach besteht. Sie können es jedoch leicht selbst implementieren.
Ich stimme jedoch einigen anderen Antworten zu, dass es besser ist, sie in einer Klasse zu kapseln, wenn Sie zwei oder mehr Objekte von einer Methode zurückgeben müssen.
quelle
Warum nicht ein
WhateverFunctionResult
Objekt erstellen , das Ihre Ergebnisse und die Logik enthält, die erforderlich ist, um diese Ergebnisse zu analysieren, dann zu wiederholen usw. Es scheint mir, dass entweder:Ich sehe, dass diese Art von Problem immer wieder auftaucht. Haben Sie keine Angst, eigene Container- / Ergebnisklassen zu erstellen, die die Daten und die zugehörigen Funktionen enthalten, um dies zu handhaben. Wenn Sie das
HashMap
Material einfach in einem oder einem ähnlichen Format weitergeben, müssen Ihre Kunden diese Karte auseinander ziehen und den Inhalt jedes Mal durchsuchen, wenn sie die Ergebnisse verwenden möchten.quelle
quelle
Dies beantwortet die Frage nicht genau, aber da jede der hier angegebenen Lösungen einige Nachteile aufweist, empfehle ich, Ihren Code ein wenig umzugestalten, sodass Sie nur einen Wert zurückgeben müssen.
Fall eins.
Sie benötigen sowohl innerhalb als auch außerhalb Ihrer Methode etwas. Warum nicht draußen berechnen und an die Methode übergeben?
Anstatt:
Versuchen:
Dies sollte die meisten Ihrer Anforderungen abdecken, da in den meisten Situationen ein Wert vor dem anderen erstellt wird und Sie die Erstellung in zwei Methoden aufteilen können. Der Nachteil ist, dass die Methode
createThingsB
im Vergleich zu einen zusätzlichen ParametercreateThings
hat und Sie möglicherweise genau dieselbe Parameterliste zweimal an verschiedene Methoden übergeben.Fall zwei.
Die offensichtlichste Lösung aller Zeiten und eine vereinfachte Version von Fall eins. Es ist nicht immer möglich, aber vielleicht können beide Werte unabhängig voneinander erstellt werden?
Anstatt:
Versuchen:
Um es nützlicher zu machen, können diese beiden Methoden eine gemeinsame Logik haben:
quelle
Übergeben Sie eine Liste an Ihre Methode, füllen Sie sie aus und geben Sie den String mit den folgenden Namen zurück:
Dann nenne es so:
quelle
Ich habe einen sehr einfachen Ansatz verwendet, um Probleme mit Mehrfachrenditen zu lösen. Es erfüllt den Zweck und vermeidet Komplexität.
Ich nenne es das String-Trennzeichen Approach
Und es ist effektiv, da es sogar Werte mehrerer Typen zurückgeben kann z. B. int, double, char, string usw.
Bei diesem Ansatz verwenden wir eine Zeichenfolge, die im Allgemeinen sehr unwahrscheinlich ist. Wir nennen es als Trennzeichen. Dieses Trennzeichen wird verwendet, um verschiedene Werte zu trennen, wenn es in einer Funktion verwendet wird
Zum Beispiel haben wir unsere endgültige Rückgabe als (zum Beispiel) intValue-Trennzeichen doubleValue-Trennzeichen ... Und dann werden wir mit dieser Zeichenfolge alle erforderlichen Informationen abrufen, die auch von verschiedenen Typen sein können
Der folgende Code zeigt die Funktionsweise dieses Konzepts
Das verwendete Trennzeichen ist ! @ # Und 3 Werte werden intVal, doubleVal und stringVal zurückgegeben
AUSGABE
quelle
In C würden Sie dies tun, indem Sie Zeiger auf Platzhalter für die Ergebnisse als Argumente übergeben:
Versuchen wir etwas Ähnliches in Java.
quelle
PASS A HASH IN DIE METHODE UND BEVÖLKERN SIE ES ......
public void buildResponse (String-Daten, Map-Antwort);
quelle