var args costruttori / metodi vs liste

5

Nel lungo dibattito sull'uso di matrici contro liste nelle classi pubbliche API di Java, tendo a preferire le liste nella maggior parte delle situazioni. Tuttavia, ho anche trovato utile usare gli argomenti var in molti costruttori e metodi, che richiedono di dichiarare un argomento del metodo (l'ultimo) come una matrice (aggiungendo implicitamente "..." prima del nome del parametro).

Dato che in molti di questi metodi desidero fornire a un programmatore la possibilità di o elencare esplicitamente gli argomenti (con var args) o utilizzare una raccolta predefinita quando si richiama il metodo, io spesso finisce per definire un costruttore o un metodo con argomenti var, e una versione sovraccaricata che accetta un elenco invece dell'array var args. Ad esempio:

public void myMethod(X ...items) {  
    myMethod(Arrays.asList(items));
}  

private void myMethod(List<X> items) {  
    ...  
}  

So che in teoria non ho bisogno di sovraccaricare il metodo sostituendo l'array var args con una lista se voglio che il programmatore invii una collezione di oggetti. Poteva semplicemente inviare un array.

Il motivo per cui faccio spesso questo è perché la maggior parte (se non tutti) dei metodi nella mia API usano liste invece di matrici, ed è un po 'strano che per uno o due metodi che richiedono la raccolta di oggetti, il programmatore deve lavorare con gli array (nei casi in cui gli argomenti var non sono convenienti). Quindi fornisco una versione sovraccaricata che funziona con l'elenco per coerenza.

Tuttavia, poiché questo è un problema ricorrente, ho la spiacevole sensazione di scrivere troppo spesso il codice boilerplate. Vorrei ricevere un feedback se la mia motivazione di mantenere la mia interfaccia coerente (accettando var array o liste, ma non costringendo il programmatore a lavorare con gli array se non proprio necessario) è sufficiente per continuare a scrivere versioni sovraccaricate usando le liste per la maggior parte dei miei metodi requirying var argument.

Vorrei sottolineare che so che per alcuni metodi gli array potrebbero essere più convenienti degli elenchi. La mia domanda riguarda situazioni in cui l'unica motivazione per dichiarare l'ultimo argomento del metodo come matrice è perché in alcuni scenari l'uso di argomenti var può essere conveniente.

Aggiorna

Grazie per il tuo feedback. Le mie conclusioni al momento sono le seguenti:

  • Riduci il più possibile l'uso di var args.
  • Continua ad aggiungere una versione sovraccaricata del metodo con var args, ad esempio l'argomento dell'array viene sostituito da un elenco (o un Iterable , come sottolineato da @Kevin), nei casi in cui può essere utile avere la scelta per invocare il metodo con var args o con una raccolta.
  • Interrompi l'utilizzo di Java il prima possibile :) (Lo sapevo già)
posta Sergio 10.02.2013 - 21:26
fonte

3 risposte

4

Stai pensando troppo al problema. Si desidera utilizzare un elenco (matrice o altro iterabile) per i propri argomenti quando è probabile che il consumatore della funzione abbia già elementi in un elenco. Si desidera utilizzare argomenti variabili quando si desidera chiamare una funzione con un numero diverso di argomenti.

Un classico esempio di quando dovresti usare vararg è C's printf() . Usare varargs ha senso qui perché, nel caso generale, non c'è motivo di mettere un gruppo di valori arbitrari in una lista solo per stampare qualcosa. Un buon esempio di dove vorresti probabilmente un elenco è un sum() in cui probabilmente stai operando su un gruppo di valori correlati che probabilmente verrebbero nascosti insieme.

Non è qualcosa su cui devi essere dogmatico o avere regole. Usa un po 'di buon senso e scrivi il codice che le persone possono seguire & non ti obbliga a saltare attraverso cerchi arbitrari.

    
risposta data 12.02.2013 - 19:23
fonte
-2

L'unica giustificazione per un cliente che desidera un vararg a cui io possa pensare è semplicemente un argomento di stile in cui non "sente" giusto per un cliente raggruppare le cose insieme in una raccolta dalla loro parte.

Un esempio potrebbe essere quando il client ha diversi DAO che implementano un'interfaccia comune, ma comunicano con origini dati logicamente distinte, come una tabella Cliente e una tabella Indirizzi. Sebbene un'app client possa utilizzare un'interfaccia comune per accedere a questi dati, i termini di query che utilizzano probabilmente non saranno gli stessi per entrambi (è possibile interrogare i clienti in base al cognome ma non si invieranno gli indirizzi in questo modo). Poiché un client non ha tipicamente un caso d'uso per iterare su un elenco di tale interfaccia, probabilmente non avranno naturalmente nascosto quei due DAO in un elenco.

Tuttavia, le liste sono una struttura dati più utile con cui lavorare rispetto agli array. Allocazione della memoria dinamica, .sublist (x, y), .clear (), iterators, ecc. Sono tutti utili per avere quale è probabilmente il motivo per cui hai già l'abitudine di usare le liste sul back-end. Quindi, perché non aspettarti che il client che chiama la tua API si senta allo stesso modo? Arrays.asList (item1, item2) è facile da usare per un client, quindi non vedo un motivo per fornire l'API varargs. Fornisci solo l'API List.

Inoltre, non sono d'accordo con il commento di Kevin sul fatto che dovresti specificare l'interfaccia Iterable nella tua API. Perdi tutte le API utili nell'interfaccia Elenco solo per salvare il tuo cliente che ha un set dal chiamare "new ArrayList (set)" e passarlo alla tua API. Almeno la tua API dovrebbe prendere una collezione.

    
risposta data 11.02.2013 - 02:54
fonte
-6

Varargs è una pessima idea nei linguaggi moderni. Era un'ipotesi di semplificazione in C, ma non avrebbe mai dovuto passare a Java o C # (il C ++ può essere perdonato perché voleva davvero essere un superset di C). Qualsiasi linguaggio che abbia un% co_de di prima classe, anche prima di generici e List , dovrebbe essere in grado di rappresentare qualsiasi funzione varargs molto meglio con un parametro di lista. E se eliminate completamente vararg, molte firme di metodi ambigue con vararg cessano di esserlo.

    
risposta data 10.02.2013 - 22:46
fonte

Leggi altre domande sui tag