искать в Java ArrayList - PullRequest
       18

искать в Java ArrayList

17 голосов
/ 12 июня 2009

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

Ответы [ 8 ]

55 голосов
/ 12 июня 2009

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

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

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

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

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

17 голосов
/ 12 июня 2009

Компилятор жалуется, потому что у вас в настоящее время есть блок 'if (существующие)' внутри вашего цикла 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, мое решение было бы похоже на то, которое опубликовал Джон Скит.

16 голосов
/ 12 июня 2009

Лично я редко пишу циклы сейчас, когда могу сойти с рук ... Я использую библиотеки Джакарты:

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

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

10 голосов
/ 12 июня 2009
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
}
2 голосов
/ 11 октября 2012

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

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

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

2 голосов
/ 12 июня 2009

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

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

1 голос
/ 20 октября 2015

В Java 8:

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

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

0 голосов
/ 22 августа 2013

Я сделал что-то близкое к этому, компилятор видит, что ваш оператор 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...