Una guida alle collezioni di Apache Commons CollectionUtils

Questo articolo fa parte di una serie: • Apache Commons Collections Bag

• SetUtils delle raccolte di Apache Commons

• Mappa ordinata delle collezioni di Apache Commons

• BidiMap delle collezioni Apache Commons

• Una guida alle collezioni di Apache Commons CollectionUtils (articolo corrente) • MapUtils delle collezioni di Apache Commons

• Guida ad Apache Commons CircularFifoQueue

1. Panoramica

In poche parole, Apache CollectionUtils fornisce metodi di utilità per operazioni comuni che coprono un'ampia gamma di casi d'uso e aiuta a evitare la scrittura di codice boilerplate. La libreria è destinata alle versioni precedenti di JVM perché attualmente una funzionalità simile è fornita dall'API Stream di Java 8 .

2. Dipendenze di Maven

Dobbiamo aggiungere la seguente dipendenza per andare avanti con CollectionUtils:

 org.apache.commons commons-collections4 4.1 

L'ultima versione della libreria può essere trovata qui.

3. Configurazione

Aggiungiamo le classi Cliente e Indirizzo:

public class Customer { private Integer id; private String name; private Address address; // standard getters and setters } public class Address { private String locality; private String city; // standard getters and setters }

Inoltre terremo a portata di mano le seguenti istanze del cliente e dell'elenco pronte per testare la nostra implementazione:

Customer customer1 = new Customer(1, "Daniel", "locality1", "city1"); Customer customer2 = new Customer(2, "Fredrik", "locality2", "city2"); Customer customer3 = new Customer(3, "Kyle", "locality3", "city3"); Customer customer4 = new Customer(4, "Bob", "locality4", "city4"); Customer customer5 = new Customer(5, "Cat", "locality5", "city5"); Customer customer6 = new Customer(6, "John", "locality6", "city6"); List list1 = Arrays.asList(customer1, customer2, customer3); List list2 = Arrays.asList(customer4, customer5, customer6); List list3 = Arrays.asList(customer1, customer2); List linkedList1 = new LinkedList(list1);

4. CollectionUtils

Esaminiamo alcuni dei metodi più utilizzati nella classe CollectionUtils di Apache Commons .

4.1. Aggiunta solo di elementi non nulli

Possiamo usare il metodo addIgnoreNull di CollectionUtils per aggiungere solo elementi non nulli a una raccolta fornita.

Il primo argomento di questo metodo è la raccolta a cui vogliamo aggiungere l'elemento e il secondo argomento è l'elemento che vogliamo aggiungere:

@Test public void givenList_whenAddIgnoreNull_thenNoNullAdded() { CollectionUtils.addIgnoreNull(list1, null); assertFalse(list1.contains(null)); }

Notare che il null non è stato aggiunto all'elenco.

4.2. Raccolta di elenchi

Possiamo usare fascicolazione metodo per raccogliere due liste già ordinati. Questo metodo accetta entrambi gli elenchi, che vogliamo unire, come argomenti e restituisce un unico elenco ordinato:

@Test public void givenTwoSortedLists_whenCollated_thenSorted() { List sortedList = CollectionUtils.collate(list1, list2); assertEquals(6, sortedList.size()); assertTrue(sortedList.get(0).getName().equals("Bob")); assertTrue(sortedList.get(2).getName().equals("Daniel")); }

4.3. Trasformare oggetti

Possiamo usare il metodo transform per trasformare oggetti di classe A in diversi oggetti di classe B. Questo metodo prende come argomenti un elenco di oggetti di classe A e un trasformatore .

Il risultato di questa operazione è un elenco di oggetti di classe B:

@Test public void givenListOfCustomers_whenTransformed_thenListOfAddress() { Collection addressCol = CollectionUtils.collect(list1, new Transformer() { public Address transform(Customer customer) { return customer.getAddress(); } }); List addressList = new ArrayList(addressCol); assertTrue(addressList.size() == 3); assertTrue(addressList.get(0).getLocality().equals("locality1")); }

4.4. Filtraggio di oggetti

Usando il filtro possiamo rimuovere oggetti che non soddisfano una data condizione da una lista . Il metodo accetta l'elenco come primo argomento e un predicato come secondo argomento.

Il metodo filterInverse fa l'opposto. Rimuove gli oggetti dall'elenco quando il predicato restituisce true.

Sia filter che filterInverse restituiscono true se l'elenco di input è stato modificato, ovvero se almeno un oggetto è stato escluso dall'elenco:

@Test public void givenCustomerList_WhenFiltered_thenCorrectSize() { boolean isModified = CollectionUtils.filter(linkedList1, new Predicate() { public boolean evaluate(Customer customer) { return Arrays.asList("Daniel","Kyle").contains(customer.getName()); } }); assertTrue(linkedList1.size() == 2); }

Possiamo usare select e selectRejected se vogliamo che l'elenco risultante venga restituito piuttosto che un flag booleano.

4.5. Controllo per non vuoto

Il metodo isNotEmpty è molto utile quando vogliamo controllare se c'è almeno un singolo elemento in un elenco. L'altro modo per controllare lo stesso è:

boolean isNotEmpty = (list != null && list.size() > 0);

Sebbene la riga di codice sopra faccia lo stesso, CollectionUtils.isNotEmpty mantiene il nostro codice più pulito:

@Test public void givenNonEmptyList_whenCheckedIsNotEmpty_thenTrue() { assertTrue(CollectionUtils.isNotEmpty(list1)); }

L'isEmpty fa il contrario. Controlla se l'elenco fornito è nullo o se non ci sono elementi nell'elenco:

List emptyList = new ArrayList(); List nullList = null; assertTrue(CollectionUtils.isEmpty(nullList)); assertTrue(CollectionUtils.isEmpty(emptyList));

4.6. Verifica dell'inclusione

Possiamo usare isSubCollection per verificare se una raccolta è contenuta in un'altra raccolta. isSubCollection accetta due raccolte come argomenti e restituisce true se la prima raccolta è una sottoraccolta della seconda raccolta:

@Test public void givenCustomerListAndASubcollection_whenChecked_thenTrue() { assertTrue(CollectionUtils.isSubCollection(list3, list1)); }

A collection is sub-collection of another collection if the number of times an object occurs in the first collection is less than or equal to the number of times it occurs in the second collection.

4.7. Intersection of Collections

We can use CollectionUtils.intersection method to get the intersection of two collections. This method takes two collections and returns a collection of elements of which are common in both the input collections:

@Test public void givenTwoLists_whenIntersected_thenCheckSize() { Collection intersection = CollectionUtils.intersection(list1, list3); assertTrue(intersection.size() == 2); }

The number of times an element occurs in the resultant collection is a minimum of the number of times it occurs in each of the given collections.

4.8. Subtracting Collections

CollectionUtils.subtract takes two collections as input and returns a collection which contains elements which are there in the first collection but not in the second collection:

@Test public void givenTwoLists_whenSubtracted_thenCheckElementNotPresentInA() { Collection result = CollectionUtils.subtract(list1, list3); assertFalse(result.contains(customer1)); }

The number of times a collection occurs in the result is the number of times it occurs in first collection minus the number of times it occurs in the second collection.

4.9. Union of Collections

CollectionUtils.union does the union of two collections and returns a collection which contains all the elements which are there in either the first or the second collection.

@Test public void givenTwoLists_whenUnioned_thenCheckElementPresentInResult() { Collection union = CollectionUtils.union(list1, list2); assertTrue(union.contains(customer1)); assertTrue(union.contains(customer4)); }

The number of times an element occurs in the resulting collection is the maximum of the number of times it occurs in each of the given collections.

5. Conclusion

And we're done.

We went through some of the commonly used methods of CollectionUtils – which is very much useful to avoid boilerplate when we're working with collections in our Java projects.

As usual, the code is available over on GitHub.

Avanti » Collezioni Apache Commons MapUtils « Collezioni Apache Commons precedenti BidiMap