web-dev-qa-db-ja.com

Java ArrayListで検索

Id番号でArrayListの顧客を検索する最良の方法を見つけようとしています。以下のコードは機能していません。コンパイラは、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

現在、forループ内に 'if(exist)'ブロックがあるため、コンパイラは不満を言っています。それはそれの外側にある必要があります。

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

そうは言っても、この検索を実行するより良い方法があります。個人的に、ArrayListを使用している場合、私のソリューションはJon Skeetが投稿したもののようになります。

17

他の人はあなたの既存のコードのエラーを指摘していますが、私はさらに2つのステップを踏みたいです。まず、Java 1.5+を使用していると仮定すると、enhanced for loopを使用して読みやすくすることができます。

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

これにより、ループする前にnullを返すというマイクロ最適化も削除されました-あなたがそれから何らかの利益を得られるとは思わず、より多くのコードです。同様に、existsフラグを削除しました。答えがわかるとすぐに返されるため、コードが簡単になります。

元のコードI 思考にバグがあったことに注意してください。インデックスiの顧客が正しいIDを持っていることがわかったので、インデックスidの顧客を返しました-これが本当にあなたが意図したものであるとは思いません。

次に、IDで多くの検索を行う場合、顧客をMap<Integer, Customer>

55
Jon Skeet

個人的には、ループをうまく処理できるのに自分でループを書くことはめったにありません... Jakarta commons libsを使用します。

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

わーい! 1行保存しました!

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

そのトピックがかなり古い場合でも、何か追加したいと思います。クラスのequalsを上書きし、getIdを比較する場合、次を使用できます。

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

もちろん、IndexOutOfBounds- Exceptionをチェックする必要があります。これは、nullポインターまたはカスタムCustomerNotFoundExceptionに変換される可能性があります。

2
Markus

リストサイズが0の場合、forループは実行されないため、ifが実行されず、したがって返されないため、returnステートメントがありません。

Ifステートメントをループの外に移動します。

2
Will Hartung

In Java 8:

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

また、戻り値の型をOptional<Customer>に変更することをお勧めします。

1
cbag

私はそれに近い何かをしました、コンパイラはあなたのreturn文がIf()文の中にあることを見ています。このエラーを解決する場合は、Ifステートメントの前にcustomerIdという新しいローカル変数を作成し、ifステートメント内に値を割り当てます。 ifステートメントの後、returnステートメントを呼び出して、cstomerIdを返します。このような:

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