2015-06-09 7 views
15

Stavo refactoring qualche vecchio codice di mine che ho scritto e ho stumbeled su questo codice:Qualsiasi alternativa sicura e netta a ArrayList.addAll?

List<OcmImageData> fullImagePool = new ArrayList<>(); 
    if (CollectionUtils.isNotEmpty(style.getTestMH())) { 
     fullImagePool.addAll(style.getTestMH()); 
    } 
    if (CollectionUtils.isNotEmpty(style.getTrousers())) { 
     fullImagePool.addAll(style.getTrousers()); 
    } 
    if (CollectionUtils.isNotEmpty(style.getDetailRevers())) { 
     fullImagePool.addAll(style.getDetailRevers()); 
    } 
    if (CollectionUtils.isNotEmpty(style.getDetailCuffs())) { 
     fullImagePool.addAll(style.getDetailCuffs()); 
    } 
    if (CollectionUtils.isNotEmpty(style.getDetailInner())) { 
     fullImagePool.addAll(style.getDetailInner()); 
    } 
    if (CollectionUtils.isNotEmpty(style.getDetailMaterial())) { 
     fullImagePool.addAll(style.getDetailMaterial()); 
    } 
    if (CollectionUtils.isNotEmpty(style.getComposing())) { 
     fullImagePool.addAll(style.getComposing()); 
    } 
    ... 

Quindi, in pratica ho bisogno di creare un ArrayList che contiene tutti gli elenchi qui fa riferimento, in quanto questi possono essere null (vengono scaricati dal database da un framework di origine chiuso e, sfortunatamente, sono nulli se non trova nulla), ho bisogno di controllare ogni volta se la raccolta non è nullo per aggiungerli in questo pool che sembra solo strano.

Esiste una libreria o classe di utilità Framework Collection che mi consente di aggiungere una raccolta a un'altra senza eseguire il controllo Null-safe?

+3

I_strongly_ raccomando di creare un wrapper attorno al framework di cacky closed source per non restituire 'null', restituendo invece una lista vuota, quindi non devi preoccuparti di questo mai più. Usare 'null' invece di una raccolta vuota è essenzialmente sempre una pessima idea. –

+0

Perché? Se i riferimenti di elenco nulli sono semanticamente uguali a quelli vuoti, perché non utilizzare solo elenchi vuoti? E se sono semanticamente diversi, perché vuoi trovare una biblioteca che li tratti semanticamente della stessa cosa? – EJP

risposta

6

Questo refactors modo pulito per

for (OcmImageData elem : new List<OcmImageData>[] { style.getTestMH(), style.getTrousers() /* etc */}) { 
    if (CollectionUtils.isNotEmpty(elem)) { 
     fullImagePull.addAll(elem); 
    } 
} 

Per rispondere alla tua domanda iniziale, no, si dovrà fare il proprio assegno nullo. È possibile vedere Guava's methods will throw an NPE e i metodi di Apache explicitly require the input to be not null.

+0

Hmm cool construction. Non sapevo nemmeno questo:) – ZeDonDino

+0

Se questo è "pulito" o non è in qualche modo discutibile, specialmente se ci sono decine di opzioni. :-) – user949300

+0

@ user949300 il controllo null non viene duplicato N volte. – djechlin

19

Basta scrivere un piccolo metodo di utilità:

public static <E> void addAllIfNotNull(List<E> list, Collection<? extends E> c) { 
    if (c != null) { 
     list.addAll(c); 
    } 
} 

in modo che si può scrivere:

List<OcmImageData> fullImagePool = new ArrayList<>(); 
addAllIfNotNull(fullImagePool, style.getTestMH()); 
addAllIfNotNull(fullImagePool, style.getTrousers()); 
addAllIfNotNull(fullImagePool, style.getDetailRevers()); 
// ...etc 
+1

Mi piace il concept e il upvoted, ma questo mi sembra un po 'troppo specifico. Vorrei scrivere un'utilità più generale, 'convertNullToEmpty (Collection inMightBeNull)'; (generici omessi per semplicità poiché questo è un commento)). Quindi usa 'fullImagePool.addAll (convertNullToEmpty (style.getXXX())); ' – user949300

9

Utilizzo di Java 8:

List<OcmImageData> fullImagePool = Stream.of(style.getTestMH(), /* etc */) 
             .filter(Objects::nonNull) 
             .flatMap(l -> l.stream()) 
             .collect(Collectors.toList()); 
+1

Probabilmente dovresti usare' CollectionUtils :: isNotEmpty' invece di 'Objects :: nonNull' per mantenere la semantica dell'OP. –

+0

Potrei, ma coprirebbe la bellezza di '' FlatMap'' –

+0

Supponendo 'CollectionUtils :: isNotEmpty' non fa nulla di più (in realtà non dice). Tuttavia, la domanda richiede chiaramente i controlli nulli quindi immagino che sia positivo in entrambi i casi. –

11

In Java 8 Uso di seguito il codice: -

Optional.ofNullable(listToBeAdded).ifPresent(listToBeAddedTo::addAll) 

listToBeAdded - L'elenco di cui è necessario aggiungere gli elementi. listToBeAddedTo - L'elenco a cui si aggiungono gli elementi utilizzando addAll.

+1

Ho aggiornato il metodo Utility in un'altra risposta, ma ora vedo questa risposta e ora la utilizzo. Questo dovrebbe essere quello contrassegnato come la migliore risposta corretta, IMO. – user1567291