2015-03-17 3 views
15

Я создал список объектов, и есть люди, добавили к нему:Удалить элементы из ArrayList с определенным значением

ArrayList<Person> peeps = new ArrayList<Person>(); 

peeps.add(new Person("112", "John", "Smith")); 
peeps.add(new Person("516", "Jane", "Smith")); 
peeps.add(new Person("114", "John", "Doe")); 

Я пытаюсь выяснить, как удалить человека из списка по номеру. Поэтому, если бы я хотел удалить человека с идентификационным номером 114, но не сейчас, где он упал в списке, как бы я?

+5

Вы должны использовать ArrayList? Вам будет намного лучше с HashMap . – lacraig2

+2

Вы не выбрали нужную структуру данных для своей проблемы. Используйте «Карта», а не «Список». – Asaph

+0

Можете ли вы расширить свой класс Person? – ddagsan

ответ

12

Если вы собираетесь использовать ArrayList, единственный способ - пройти через весь список, глядя на каждого человека, и, увидев его, его идентификационный номер - 114. Для более крупных наборов данных это не будет эффективным и этого следует избегать.

Если вы можете изменить структуру данных, тогда какой-то Map будет лучше (HashMap, как правило, хороший выбор). У вас может быть номер id как «ключ», а затем ассоциировать его с каждым человеком. Позже вы можете запросить ключ по карте. Зэк, что вы можете иметь только одно значение в качестве ключа, так что вы не можете иметь скажем как имя и идентификационный номер клавиши

Edit:
более эффективный способ сделать использовать ArrayList будет держать его отсортировано по идентификационный номер. Затем вы можете использовать что-то вроде Collections.binarySearch() для быстрого доступа к элементам по номеру id. Кон - это то, что дорогое удаление из/вставки в отсортированный массив, так как все, что нужно, нужно перемещать. Поэтому, если вы собираетесь делать относительно немного изменений по сравнению с количеством чтений, это может быть жизнеспособным.

+1

Хороший ответ, но это не единственный способ. Хорошее предложение о карте. – m0skit0

3

iterate в ArrayList элементов и удалить те, которые соответствуют строку, которую вы хотите удалить: В Iterator remove операции безопасен и не создает ConcurrentModificationException

for (Iterator<String> iterator = peeps.iterator(); elementToCheck = iterator.next();) { 
    if (elementToCheck.getId().equals("112")) { 
     // Remove the current element from the iterator and the list. 
     iterator.remove(); 
    } 
} 
+2

Я считаю, что это вызовет «ConcurrentModificationException» .. –

+0

Правда. Я изменил это. Удаление Iterator безопасно и не вызывает этого исключения. – adrCoder

+0

Вы можете просто поместить 'elementToCheck = iterator.next()' в 'for';;) – m0skit0

32

Использование Java8:

peeps.removeIf(p -> p.getId().equals("112")); 

Обратите внимание, что это эквивалентно линейному поиску и займет O(n) времени. Если эта операция повторяется часто, рекомендуется использовать HashMap, чтобы ускорить работу до O(1).

Альтернативно, используя отсортированный список, вы также можете сделать трюк, но требуется O(log n) времени.

+1

Приятный, используя ямба-выражения Java 8 и новые функции. – m0skit0

+1

приятно использовать –

+0

Awesome! Хорошее использование SE 8! Сэкономил мне массу неприятностей, чтобы пройти через этот объект. –

3

Прежде всего необходимо иметь рабочий equals в вашем классе Person (что вам нужно). Тогда вы можете просто использовать List#indexOf и List#remove. Например:

final Person toRemove = new Person("112"); 
peeps.remove(peeps.indexOf(toRemove)); 

(при условии, что идентификатор личности уникален).

В качестве альтернативы, если ваш список является ArrayList вы можете использовать ArrayList#remove(Object):

final Person toRemove = new Person("112"); 
peeps.remove(toRemove); 

Если вы используете Java 8, вы можете использовать Paul's solution.

4

Существует много способов решить эту проблему.

  1. Мое любимое занятие CollectionUtils от apache.common.collection4 или его эквивалента google.а затем выберите то, что вы хотите, используя предикат или в java 8 - выражение лямбда.

    CollectionUtils.select(peeps, new Predicate<Person>() { @Override public boolean evaluate(Person object) { return object.getId().equals("114"); } });

  2. использовать старый добрый итератора и петля над ним

    Iterator<Person> iterator = peeps.iterator(); while(iterator.hasNext()) { Person next = iterator.next(); if(next.getId().equals("114")) { iterator.remove(); } }

-1
class Processor{ 

ArrayList<Person> peeps = new ArrayList<Person>(); 

void setPeeps(){ 
    peeps.add(new Person(112, "John", "Smith")); 
    peeps.add(new Person(516, "Jane", "Smith")); 
    peeps.add(new Person(114, "John", "Doe")); 
} 

void removePerson(int id){ 
    for(int i=0; i <= peeps.size(); i++){ 
     Person person = peeps.get(i); 
     if(person.id == id) 
      peeps.remove(peeps.get(i)); 
    } 
} 

void displayPersonsList(){ 
    for(Person person : peeps){ 
     System.out.println(person.id + ":" + person.fName + ":" + person.lName); 
    } 
} 

public static void main(String args[]){ 
    Processor objProcessor = new Processor(); 
    objProcessor.setPeeps(); 
    objProcessor.removePerson(114); 
    objProcessor.displayPersonsList(); 
} 
} 

class Person{ 
int id; 
String fName; 
String lName; 

public Person(int id, String fName, String lName){ 
    this.id = id; 
    this.fName = fName; 
    this.lName = lName; 
} 
} 
+1

Этот код имеет несколько ошибок. Это не работает. – Radiodef

+0

Я не просто вводил код здесь. Я попробовал его на STS, запустил, а затем скопировал. Можете ли вы опубликовать свою ошибку здесь? Я попробовал еще раз, это работает! –

+0

@JobinThomas попробуйте удалить любую запись, кроме последней! (если вы все еще читаете сайт) –

Смежные вопросы