web-dev-qa-db-fra.com

rechercher dans Java ArrayList

J'essaie de trouver la meilleure façon de rechercher un client dans un ArrayList par son numéro d'identification. Le code ci-dessous ne fonctionne pas; le compilateur me dit que je manque une instruction return.

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;
}
17
fenec

Le compilateur se plaint car vous avez actuellement le bloc 'if (exist)' à l'intérieur de votre boucle for. Il doit être en dehors de cela.

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);
}

Cela étant dit, il existe de meilleures façons d'effectuer cette recherche. Personnellement, si j'utilisais une ArrayList, ma solution ressemblerait à celle que Jon Skeet a publiée.

17
Brandon E Taylor

D'autres ont signalé l'erreur dans votre code existant, mais je voudrais aller plus loin. Tout d'abord, en supposant que vous utilisez Java 1.5+, vous pouvez obtenir une meilleure lisibilité en utilisant amélioré pour la boucle:

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

Cela a également supprimé la micro-optimisation consistant à renvoyer null avant de boucler - je doute que vous en tiriez un avantage, et c'est plus de code. De même, j'ai supprimé le drapeau exists: retourner dès que vous connaissez la réponse rend le code plus simple.

Notez que dans votre code d'origine, je pensez vous aviez un bug. Après avoir constaté que le client de l'index i avait le bon ID, vous avez ensuite renvoyé le client de l'index id - Je doute que ce soit vraiment ce que vous vouliez.

Deuxièmement, si vous devez effectuer de nombreuses recherches par ID, avez-vous envisagé de placer vos clients dans un Map<Integer, Customer>?

55
Jon Skeet

Personnellement, j'écris rarement des boucles moi-même maintenant quand je peux m'en tirer ... J'utilise les bibliothèques de Jakarta commons:

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

Yay! J'ai enregistré une ligne!

16
Dan Gravell
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
}
11
Lucero

Même si ce sujet est assez ancien, j'aimerais ajouter quelque chose. Si vous écrasez equals pour vos classes, afin de comparer votre getId, vous pouvez utiliser:

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

Bien sûr, vous devez vérifier une IndexOutOfBounds- exception, qui peut être traduite en un pointeur nul ou en un CustomerNotFoundException personnalisé.

2
Markus

Il vous manque l'instruction return car si la taille de votre liste est 0, la boucle for ne s'exécutera jamais, donc l'if ne s'exécutera jamais, et donc vous ne reviendrez jamais.

Déplacez l'instruction if hors de la boucle.

2
Will Hartung

Dans Java 8:

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

Il peut également être préférable de changer le type de retour en Optional<Customer>.

1
cbag

J'ai fait quelque chose de proche de cela, le compilateur voit que votre déclaration de retour est dans une instruction If (). Si vous souhaitez résoudre cette erreur, créez simplement une nouvelle variable locale appelée customerId avant l'instruction If, puis affectez une valeur à l'intérieur de l'instruction if. Après l'instruction if, appelez votre instruction return et retournez cstomerId. Comme ça:

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);
        }
    }
    return customerId;
}
0
Alan Sorrill