Come trovare un elemento in un elenco con Java

1. Panoramica

Trovare un elemento in un elenco è un'attività molto comune che incontriamo come sviluppatori.

In questo breve tutorial, tratteremo diversi modi in cui possiamo farlo con Java.

2. Configurazione

Per prima cosa iniziamo definendo un POJO del cliente :

public class Customer { private int id; private String name; // getters/setters, custom hashcode/equals }

Quindi un ArrayList di clienti:

List customers = new ArrayList(); customers.add(new Customer(1, "Jack")); customers.add(new Customer(2, "James")); customers.add(new Customer(3, "Kelly")); 

Nota che abbiamo sovrascritto hashCode ed equals nella nostra classe Customer .

In base alla nostra attuale implementazione di uguale , due oggetti Cliente con lo stesso ID saranno considerati uguali.

Useremo questo elenco di clienti lungo il percorso.

3. Utilizzo dell'API Java

Java stesso fornisce diversi modi per trovare un elemento in un elenco:

  • Il metodo contiene
  • Il metodo indexOf
  • Un ciclo for ad hoc
  • L' API Stream

3.1. contiene ()

List espone un metodo chiamato contiene :

boolean contains(Object element)

Come suggerisce il nome, questo metodo restituisce true se l'elenco contiene l' elemento specificato e restituisce false in caso contrario.

Quindi, quando dobbiamo controllare se un elemento specifico esiste nel nostro elenco, possiamo:

Customer james = new Customer(2, "James"); if (customers.contains(james)) { // ... }

3.2. indice di()

indexOf è un altro metodo utile per trovare elementi:

int indexOf(Object element)

Questo metodo restituisce l'indice della prima occorrenza dell'elemento specificato nell'elenco fornito o -1 se l'elenco non contiene l' elemento .

Quindi logicamente, se questo metodo restituisce qualcosa di diverso da -1, sappiamo che l'elenco contiene l'elemento:

if(customers.indexOf(james) != -1) { // ... }

Il vantaggio principale dell'utilizzo di questo metodo è che può dirci la posizione dell'elemento specificato nell'elenco fornito.

3.3. Looping di base

E se volessimo fare una ricerca basata sul campo per un elemento? Ad esempio, supponiamo che stiamo annunciando una lotteria e dobbiamo dichiarare un cliente con un nome specifico come vincitore.

Per tali ricerche sul campo, possiamo passare all'iterazione.

Un modo tradizionale per scorrere un elenco consiste nell'usare uno dei costrutti di ciclo di Java. In ogni iterazione, confrontiamo l'elemento corrente nell'elenco con l'elemento che stiamo cercando per vedere se è una corrispondenza:

public Customer findUsingEnhancedForLoop( String name, List customers) { for (Customer customer : customers) { if (customer.getName().equals(name)) { return customer; } } return null; }

Qui il nome si riferisce al nome che stiamo cercando nell'elenco di clienti fornito . Questo metodo restituisce il primo oggetto Customer nell'elenco con un nome corrispondente o null se non esiste alcun Customer .

3.4. Looping con un iteratore

L'iteratore è un altro modo in cui possiamo attraversare un elenco di elementi.

Possiamo semplicemente prendere il nostro esempio precedente e modificarlo un po ':

public Customer findUsingIterator( String name, List customers) { Iterator iterator = customers.iterator(); while (iterator.hasNext()) { Customer customer = iterator.next(); if (customer.getName().equals(name)) { return customer; } } return null; }

Di conseguenza, il comportamento è lo stesso di prima.

3.5. API Java 8 Stream

A partire da Java 8, possiamo anche utilizzare l' API Stream per trovare un elemento in un elenco.

Per trovare un elemento che corrisponde a criteri specifici in un dato elenco, noi:

  • invoca stream () nell'elenco
  • chiamare il metodo f ilter () con un predicato appropriato
  • chiama il costrutto findAny () , che restituisce il primo elemento che corrisponde al predicato del filtro racchiuso in un Opzionale se tale elemento esiste

Customer james = customers.stream() .filter(customer -> "James".equals(customer.getName())) .findAny() .orElse(null);

Per comodità, impostiamo il valore predefinito su null nel caso in cui un optional sia vuoto, ma questa potrebbe non essere sempre la scelta migliore per ogni scenario.

4. Biblioteche di terze parti

Now, while the Stream API is more than sufficient, what should we do if we're stuck on an earlier version of Java?

Fortunately, there are many third-party libraries like Google Guava and Apache Commons which we can use.

4.1. Google Guava

Google Guava provides functionality that is similar to what we can do with streams:

Customer james = Iterables.tryFind(customers, new Predicate() { public boolean apply(Customer customer) { return "James".equals(customer.getName()); } }).orNull();

Just like with Stream API, we can optionally choose to return a default value instead of null:

Customer james = Iterables.tryFind(customers, new Predicate() { public boolean apply(Customer customer) { return "James".equals(customer.getName()); } }).or(customers.get(0));

The above code will pick the first element in the list if no match is found.

Also, don't forget that Guava throws a NullPointerException if either the list or the predicate is null.

4.2. Apache Commons

We can find an element in almost the exact same way using Apache Commons:

Customer james = IterableUtils.find(customers, new Predicate() { public boolean evaluate(Customer customer) { return "James".equals(customer.getName()); } });

Tuttavia, ci sono un paio di differenze importanti:

  1. Apache Commons restituisce solo null se passiamo un elenco null .
  2. Itnon fornisce funzionalità di valore predefinito come tryFind di Guava .

5. conclusione

In questo articolo, abbiamo imparato diversi modi per trovare un elemento in un elenco, eseguendo controlli rapidi di esistenza e terminando con ricerche sul campo.

Abbiamo anche esaminato le librerie di terze parti Google Guava e Apache Commons come alternative all'API Java 8 Streams .

Grazie per essere passato e ricordati di controllare tutte le fonti per questi esempi su GitHub.