2013-03-04 13 views
5

mi sembrano creare questi due tipi di metodi di tanto in tanto:Raccolta errori in un metodo Java, ArrayList vuoto contro LinkedList

// return null on errors, and append errors to 2nd param, otherwise return result 
String fetchSomething(String parameter, List<String> errorMessagesOut); 

// return empty list or null on no errors, otherwise list of errors 
List<String> verifySomething(String parameter); 

E poi il codice che chiama queste si uniranno alla lista degli errori con separatore appropriato (ad esempio come semplice virgola, newline, tag HTML ...), di solito usando il metodo Apache Commons Stringutils.join. E nel caso normale non ci sono errori, e la lista sarà vuota.

Così, ho cominciato a pensare a queste due domande:

  1. Vedete un problema con il ritorno le stringhe dei messaggi di errore come lista? Se è così, qual è l'alternativa migliore? (non eccezioni, che sarebbero scagliati dal codice che chiama questi metodi, quando questo è voluto.)

  2. Is new LinkedList() o new ArrayList(0) o new ArrayList() migliore per la lista che è prevede a rimanere vuota, e che dovrebbe normalmente hanno solo accesso iteratore sequenziale quando non è vuoto?


EDIT: caso d'uso Esempio:

List<String> verifyParameters(JSONObject params) { 
    List<String> ret = new ArrayList<String>(0); 

    if (!verifyKey(params.get("key"))) 
     ret.add("Invalid key: " + key); 

    if (!verifyAccess(params.get("user"), params.get("pass"))) 
     ret.add("Authentication error"); 

    return ret; 
} 

...

List<String> errors = verifyParameters(params); 
if (!errors.isEmpty()) { 

    connection.sendErrorListMessage(errors); 
    logger.warn(StringUtils.join(errors, ", ")); 
    controlPanel.show("Errors: \n- " + StringUtils.join(errors, "\n- ") + '\n'); 
    throw new AbortException("invalid params); // or maybe return false/null; 
} 
// proceed with valid params 

Di solito la gestione della lista degli errori non avrebbero tutti coloro, si cerca solo per illustrare il punto in cui la lista degli errori è una lista di messaggi che gli umani devono vedere, indipendentemente da come verranno mostrati, e anche non relativi a/utili per la gestione d ifferent errors differently.

+3

Mantieni semplice, usa 'new ArrayList()'. Se vedi problemi successivi, cambialo in 'new ArrayList (0)' o anche per 'new LinkedList()'. Micro ottimizzazione è la radice di tutti i mali –

+0

@LuiggiMendoza - Mi piace il fatto che sei stato in grado di usare quella citazione due volte in cinque minuti :) nice – cowls

+0

LinkedList ovviamente come struttura dati adeguata. Restituire una lista invece di lasciare che un parametro sia riempito, è più leggibile. –

risposta

3

Penso che sia corretto usare un elenco per le stringhe.Sarei propenso a fare un Result classe dedicata almeno per fetchSomthing e renderlo in questo modo, soprattutto se il errorMessagesOut passato non è mai nulla, se non un nuovo elenco vuoto:

Result result = fetchSomething(String parameter); 
if (result.hasErrors()) { 
    List<String> errors = result.getErrors(); 
} else { 
    String fetched = result.getValue(); 
} 

Vorrei quindi anche mettere uno qualsiasi dei metodi quel processo stringhe di errore in questa classe anche in modo che si possa fare qualcosa di simile:

String errorMessage = result.getErrorString(); 

questo incapsula i dati di errore e la formattazione di esso all'interno della una classe e significa che, nel caso di errori non lo fai è necessario creare qualsiasi Elenco internamente nell'istanza Risultato.

I miei punti sopra riportati riguardano principalmente la progettazione del codice. Non ha senso provare la micro-ottimizzazione senza profilare e avere benchmark da confrontare con i risultati di eventuali modifiche.

1

A cosa servono questi errori? Hai intenzione di prendere una decisione aziendale dagli errori restituiti da un metodo? Altrimenti, se gli errori sono solo per la registrazione, una semplice soluzione di registrazione suggerirebbe che gli errori vengano registrati non appena si verificano. Sto parlando di quelli logger.debug("Error message");.

In ogni caso, potresti darci un esempio di cosa viene fatto a questi errori dopo che sono stati restituiti?

Una cosa che punto, però: tende ad essere fonte di confusione se si utilizza lo stesso array/elenco/raccolta per entrambi i risultati di elaborazione e per errori. Sarebbe anche confuso se i metodi restituissero liste di errori (o elenchi vuoti/nulli in caso di errore), poiché sembrerebbe che gli errori siano il risultato stesso dell'esecuzione del metodo.

+0

Ho aggiunto un esempio di utilizzo semplificato. In ogni caso, l'intenzione è di ottenere * tutti * errori, non solo rinunciare al primo. – hyde

1

Non c'è niente di sbagliato nel provare a raccogliere tutte le informazioni di errore usando una lista. Utilizzando un ArrayList funzionerà bene, non c'è bisogno di preoccuparsi di questo ...

Se si sa che non ci sono errori si potrebbe return Collections.emptyList();.

In generale con le raccolte evitare di restituire sia null o elenco vuoto. Uso sempre la lista vuota in quanto non si rompe per i loop.

1

Si vede un problema con la restituzione delle stringhe dei messaggi di errore come elenco? Se quindi, qual è l'alternativa migliore?

No. Non c'è niente di sbagliato nell'usare un elenco se risolve il problema.

è new LinkedList() o new ArrayList(0) o new ArrayList() meglio lista che dovrebbe rimanere vuoto, e che dovrebbero normalmente avere solo sequenziale accesso iteratore quando non è vuota?

Conoscere quanti elementi della lista sta per archiviare e istanziare la lista con quella capacità non avrà alcun miglioramento significativo nelle prestazioni:

Ogni istanza ArrayList ha una capacità. La capacità è la dimensione di della matrice utilizzata per memorizzare gli elementi nell'elenco. È sempre allo meno grande della dimensione dell'elenco. Quando gli elementi vengono aggiunti a un ArrayList , la sua capacità aumenta automaticamente. I dettagli della politica di crescita non sono specificati al di là del fatto che l'aggiunta di un elemento ha il costo di ammortamento costante ammortizzato .

Potrai comunque risparmiare un po 'di memoria con new ArrayList(0) se la lista è più spesso vuota come la dimensione della lista è inizializzato a 10 quando non viene specificata alcuna capacità iniziale.