Искать в java ArrayList

Я пытаюсь найти лучший способ поиска клиента в 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;
}

Ответы

Ответ 1

Компилятор жалуется, потому что в настоящее время у вас есть блок if (exist) внутри вашего цикла for. Он должен быть вне его.

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, мое решение было бы похоже на то, которое опубликовал Джон Скит.

Ответ 2

Другие указали на ошибку в вашем существующем коде, но я хотел бы сделать еще два шага. Во-первых, если вы используете Java 1.5+, вы можете добиться большей читаемости с помощью расширенного цикла:

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

Это также удалило микро-оптимизацию возврата null перед циклом - я сомневаюсь, что вы получите от нее какую-то выгоду, и это больше кода. Аналогично, я удалил флаг exists: возврат, как только вы узнаете ответ, делает код более простым.

Обратите внимание, что в вашем исходном коде я думаю, что у вас была ошибка. Обнаружив, что у клиента с индексом i был правильный идентификатор, вы вернули клиента по индексу id - я сомневаюсь, что это действительно то, что вы намеревались.

Во-вторых, если вы собираетесь делать много запросов по идентификатору, считаете ли вы, что ваши клиенты стали Map<Integer, Customer>?

Ответ 3

Лично я редко пишу петли себе сейчас, когда я могу уйти с этим... Я использую 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;
        }
    });
}

Ура! Я сохранил одну строку!

Ответ 4

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
}

Ответ 5

У вас отсутствует оператор return, потому что, если ваш размер списка равен 0, цикл for никогда не будет выполняться, поэтому if никогда не будет запущен, и таким образом вы никогда не вернетесь.

Переместите оператор if из цикла.

Ответ 6

Даже если эта тема довольно старая, я бы хотел что-то добавить. Если вы переписываете equals для своих классов, поэтому он сравнивает ваш getId, вы можете использовать:

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

Конечно, вам нужно будет проверить IndexOutOfBounds -Exception, которое должно быть переведено в нулевой указатель или пользовательский CustomerNotFoundException.

Ответ 7

В Java 8:

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

Также лучше изменить тип возврата на Optional<Customer>.

Ответ 8

Я сделал что-то близкое к этому, компилятор видит, что ваш оператор return находится в инструкции If(). Если вы хотите разрешить эту ошибку, просто создайте новую локальную переменную customerId перед оператором If, а затем присвойте значение внутри оператора 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;

}