2009-06-12 13 views
15

Sto cercando di capire il modo migliore per cercare un cliente in un ArrayList con il suo numero di identificazione. Il codice qui sotto non funziona; il compilatore mi dice che mi manca un'istruzione return.cerca in java ArrayList

Customer findCustomerByid(int id){ 
    boolean exist=false; 

    if(this.customers.isEmpty()) { 
     return null; 
    } 

    for(int i=0;i<this.customers.size();i++) { 
     if(this.customers.get(i).getId() == id) { 
      exist=true; 
      break; 
     } 

     if(exist) { 
      return this.customers.get(id); 
     } else { 
      return this.customers.get(id); 
     } 
    } 

} 

//the customer class is something like that 
public class Customer { 
    //attributes 
    int id; 
    int tel; 
    String fname; 
    String lname; 
    String resgistrationDate; 
} 
+12

Uno dei principali Java Buone Pratiche è di usare sempre le parentesi, anche se il blocco ha una sola frase per evitare problemi come il vostro –

risposta

16

Il compilatore si lamenta perché al momento esiste il blocco "if (esiste)" all'interno del ciclo for. Deve essere al di fuori di esso.

for(int i=0;i<this.customers.size();i++){ 
     if(this.customers.get(i).getId() == id){ 
      exist=true; 
      break; 
     } 
} 

if(exist) { 
    return this.customers.get(id); 
} else { 
    return this.customers.get(id); 
} 

Detto questo, ci sono modi migliori per eseguire questa ricerca. Personalmente, se stavo usando un ArrayList, la mia soluzione sarebbe simile a quella che Jon Skeet ha pubblicato.

+0

Sì reformated e ora è più evidente –

+0

ho il forte sospetto che il codice è ancora rotto anche se (nota l'argomento per customers.get alla fine). Il fatto che abbia ancora un "if/else" in cui entrambi i rami hanno lo stesso codice è profondamente sospetto! –

+0

Sono d'accordo, Jon. Inoltre, ci sono certamente modi migliori per eseguire la ricerca (come indicato da diversi altri poster). –

10
Customer findCustomerByid(int id){ 
    for (int i=0; i<this.customers.size(); i++) { 
     Customer customer = this.customers.get(i); 
     if (customer.getId() == id){ 
      return customer; 
     } 
    } 
    return null; // no Customer found with this ID; maybe throw an exception 
} 
+0

se l'istruzione non è sufficiente per correggere il metodo. La tua soluzione è preferita. +1 – waxwing

+0

Sono abbastanza d'accordo. +1 –

2

ti manca l'istruzione return, perché se la dimensione elenco è 0, il ciclo for non sarà mai eseguito, quindi il caso non verrà mai eseguito, e quindi si potrà mai tornare.

Sposta l'istruzione if fuori dal ciclo.

48

Altri hanno segnalato l'errore nel codice esistente, ma vorrei fare ancora due passi. In primo luogo, supponendo che si sta utilizzando Java 1.5+, è possibile ottenere una maggiore leggibilità utilizzando il maggiore ciclo for:

Customer findCustomerByid(int id){  
    for (Customer customer : customers) { 
     if (customer.getId() == id) { 
      return customer; 
     } 
    } 
    return null; 
} 

Questo ha anche rimosso il micro-ottimizzazione del ritorno null prima di loop - dubito che si' Ne trarrai vantaggio, ed è più codice. Allo stesso modo ho rimosso il flag exists: restituendo appena possibile la risposta rende il codice più semplice.

Si noti che nel codice originale I si è verificato un errore. Avendo riscontrato che il cliente all'indice i aveva l'ID corretto, il cliente l'ha restituito all'indice id - Dubito che questo sia davvero ciò che intendevi.

In secondo luogo, se avete intenzione di fare un sacco di ricerche per ID, avete considerato mettere i clienti in una Map<Integer, Customer>?

16

Personalmente Ho raramente scrivere loop me stessa quando posso farla franca ... Io uso le Jakarta Commons librerie:

Customer findCustomerByid(final int id){ 
    return (Customer) CollectionUtils.find(customers, new Predicate() { 
     public boolean evaluate(Object arg0) { 
      return ((Customer) arg0).getId()==id; 
     } 
    }); 
} 

Yay! Ho salvato una riga!

+1

Hai salvato una riga per ogni volta che scrivi una funzione find() :-) Non c'è da starnutire! –

+0

Potresti "salvare" una riga di codice ogni volta che scrivi, ma scommetto che se hai visto come funziona quella funzione di ricerca, vedrai che sta usando un ciclo for. Quindi bisogna chiedersi se hai davvero "salvato" delle righe o aggiunto più linee al codice di sottolineatura? ;) – Spider

+2

@Spider L'esecuzione del runtime è solo un modo per misurare il codice ... ci sono altri vantaggi nell'avere codice meno ripetuto. –

2

Anche se l'argomento è piuttosto vecchio, vorrei aggiungere qualcosa. Se si sovrascrive equals per voi le classi, in modo che confronta la getId, è possibile utilizzare:

customer = new Customer(id); 
customers.get(customers.indexOf(customer)); 

Naturalmente, si avrebbe dovuto verificare la presenza di un IndexOutOfBounds -Exception, che oculd essere tradotto in un puntatore nullo o un'usanza CustomerNotFoundException.

0

Ho fatto qualcosa di simile, il compilatore sta vedendo che la dichiarazione di ritorno è in un'istruzione If(). Se si desidera risolvere questo errore, è sufficiente creare una nuova variabile locale chiamata customerId prima dell'istruzione If, ​​quindi assegnare un valore all'interno dell'istruzione if. Dopo l'istruzione if, chiama la dichiarazione di reso e restituisci cstomerId. Ti piace questa: customerId

Customer findCustomerByid(int id){ 
boolean exist=false; 

if(this.customers.isEmpty()) { 
    return null; 
} 

for(int i=0;i<this.customers.size();i++) { 
    if(this.customers.get(i).getId() == id) { 
     exist=true; 
     break; 
    } 

    int customerId; 

    if(exist) { 
     customerId = this.customers.get(id); 
    } else { 
     customerId = this.customers.get(id); 
    } 
} 

di ritorno;

}

1

In Java 8:

Customer findCustomerByid(int id) { 
    return this.customers.stream() 
     .filter(customer -> customer.getId().equals(id)) 
     .findFirst().get(); 
} 

Potrebbe anche essere meglio cambiare il tipo di ritorno a Optional<Customer>.