2012-05-13 22 views
5

Preambolo: Sono consapevole di utilizzare un elenco o altre collezioni per restituire un risultato, ma poi devo passare attraverso la lista spennare i risultati fuori: vedi 2 ° esempioritorno più valori in Java

Preambolo-2: I 'm alla ricerca di una risposta al di là di 'questo non è supportato in Java ...'


sto cercando un modo conveniente per tornare più oggetti da una chiamata di metodo Java.

Un po 'come in PHP:

list ($obj1, $obj2, ...) foobar(); 

Sono davvero stancando di passare oggetti supporto nelle argomentazioni, ad esempio:

class Holder { 
    int value; 
} 

Holder h1=new Holder(); 
Holder h2=new Holder(); 

e poi:

o.foobar(h1,h2); 

... sarebbe molto interessato se qualcuno ha trovato un modo elegante per aggirare questo.


Utilizzando un elenco

List<String> = foobar(); 

Ci sono due svantaggi di questo:

devo mettere in valigia prima l'elenco sul lato callee della casa:

// this is on the callee side of the house 
ArrayList<String> result = new ArrayList<String> 
result.add("foo"); 
result.add("bar"); 

Poi dal lato del chiamante devo estrarre i risultati:

// This is on the caller side 
List<String> result = foobar(); 
String result1 = result.get(0); 
String result2 = result.get(1); // this is not as elegant as the PHP equivalent 

Inoltre, dire che volevo tornare oggetti di tipo diverso dire String, Integer avrei dovuto restituire un elenco di oggetti e poi gettato ogni oggetto ... non abbastanza

Grazie.

+3

Vorrei semplicemente restituire una lista – keyser

+0

Qual è il problema con la restituzione dell'elenco? –

+2

Modificato. Una "vecchia mano" a Java non avrebbe fatto questa domanda, e l'originale è sembrato un po 'snervante. –

risposta

8

L'utilizzo di una classe di tuple generica è il più vicino che possa immaginare. Per dare un'idea, tale classe di uso generale per tre valori di ritorno potrebbe essere simile a questa:

public class T3<A, B, C> { 
    A _1; 
    B _2; 
    C _3; 
    T3(A _1, B _2, C _3) { 
     this._1 = _1; 
     this._2 = _2; 
     this._3 = _3; 
    } 
} 

Questo permette un costruttore una dichiarazione sul lato callee, ad esempio:

public T3<String, Integer, Character> getValues() { 
    return new T3<String, Integer, Character>("string", 0, 'c'); 
} 

ma titolare la costruzione dell'istanza da parte del callee deve essere fatta.

Ogni numero di valori restituiti richiede una classe di tuple. Potrebbe esserci qualcosa di simile fornito nello Functional Java library. Per riferimento, ecco un N-Tuple implementation.

Per il caso di due valori java.util.AbstractMap.SimpleEntry farebbe:

return new SimpleEntry<String, Integer>("string", 0); 

Comunque, vedo due punti importanti da prendere in considerazione per i valori di ritorno multipli:

  1. valori di ritorno digitati
  2. Sottolineando il significato di ogni valore di ritorno

così noioso come si è, mi consiglia di creare una classe separata per contenere tutti i valori di risposta e dichiarare che come il metodo restituisce il tipo. In questo modo è possibile evidenziare il significato di ciascun valore.

4

È possibile restituire un List, Set o Map?

+1

Posso, ma questo è piuttosto soluzione ingombrante - fare riferimento all'esempio 2 nella mia domanda – user1172468

5

Si può avere un metodo come con una firma come questo:

List<Holder> foobar(); 
1

è possibile utilizzare qualsiasi della classe Collection per questo scopo. Questo Lesson può aiutarti a decidere cosa è più adatto a te.

+0

Ciao Grazie per la risposta, ne sono consapevole, ho chiarito che sto cercando uno dei rimedi tipici di questo. – user1172468

2

Tornando un titolare estesa sembra meglio di restituire un elenco:

class Holder { 
    int value1; 
    String value2; 
    Holder(int value1, String value2) {} 
} 

Holder foobar() { 
    return new Holder(1, "bar"); 
} 
+0

Ya, possibilmente ma verboso verboso dettagliato :-(, grazie per la risposta anche se – user1172468

+0

@ user1172468 La verosimiglianza è proprietà intrinseca di Java.A volte desidero ardentemente il typedef e la magia di overload dell'operatore, ma fanno un casino, quindi sono contento che Java sia verbose. –

2

Se è necessario restituire più valori dello stesso tipo, quindi un elenco o Set è appropriato. È perfettamente valido restituire, ad esempio, un elenco di nomi utente di lunghezza variabile come elenco. Se sai che restituirai sempre un numero fisso di valori, utilizzerei un array.Ad esempio, in un metodo che restituisce un qualche tipo di ID utente come tre interi distinti, userei:

public int[] getUserId(){ 
    int[] returnArray = new int[3]; 
    returnArray[0] = getFirstPart(); 
    returnArray[1] = getSecondPart(); 
    returnArray[2] = getThirdPart(); 

    return returnArray; 
} 

Nel codice chiamante, ottenendo i valori è semplice come array[0], array[1] e array[2]. Questo è molto più semplice di una raccolta e non si interrompe nulla, poiché gli ID utente sono definiti come tre numeri interi.

Se è davvero necessario restituire più valori distinti, quindi la classe titolare è l'opzione migliore, in nessun altro modo. Più valori di ritorno non sono supportati in Java. Ma preferirei guardare la soluzione dal punto di vista del design. Se una classe ha bisogno di restituire più valori distinti, probabilmente fa un sacco di cose, alcune delle quali non correlate ad altre. Un singolo pezzo di codice (una classe, un metodo) dovrebbe sempre avere un unico scopo chiaro e responsabilità chiaramente definite. Piuttosto che restituire più valori distinti, prenderei in considerazione la possibilità di dividere il metodo in un metodo più breve o definire un intefaccia per esternalizzare tutte le funzionalità. Se quei valori di ritorno sono correlati in qualche modo e non avrebbero significato se smontati, allora penso che meritino una lezione da soli.

Problemi correlati