Удаление элемента по условию в списке массивов

#java #arraylist

#java #список массивов

Вопрос:

Я удаляю элементы из arrayList вызываемого itemList . Я создал findItem метод для поиска элемента по его callNumber и copyNumber .

В моем remove() я использую findItem() , чтобы найти элемент, а затем удалить его. Моя проблема в том, что я все еще получаю concurrentmodificationexception ошибку.

Я попробовал расширенный цикл for (который, как я знаю, не работает), и я попробовал итератор (который должен был сработать), но все равно получил ошибку.

Это моя третья стратегия, пытающаяся заставить его работать. Какие другие стратегии позволят обойти список, удалить элемент и обойти concurrentmodificationexception ?

 /**
 * Finds an item by call number and copy number.
 *
 * @param callNumber the call number
 * @param copy the copy number
 * @return the item, if not found return null
 */
private Item getItem(String callNumber, int copy)
{

    for (int i = 0; i < numItems; i  )
    {
        Item item = itemList.get(i);
        if (item.getCallNumber() != null  
        amp;amp; item.getCallNumber().equals(callNumber) 
        amp;amp; item.getCopyNumber() == copy)
        {
            return item;
        }
    }

    return null;
}

/**
 * Deletes a item from the library.
 *
 * @param  callNumber  the call number of the item to be deleted.
 * @param  copy        the copy number of the item to be deleted.
 * @return      <code>true</code> if the item was deleted successfully,
 *              and <code> false</code> if the item was not deleted.
 */

 public boolean deleteItem(String callNumber, int copy)
{
    Item rItem = getItem(callNumber, copy);

    if(rItem == null)
    {
        return false;
    }
    if (rItem.getCallNumber().equals(callNumber)
        amp;amp; rItem.getCopyNumber() == copy)
    {
        itemList.remove(rItem);       
        numItems--;
        return true;
    }

    return false;

}
  

Мой желаемый результат — удалить указанный элемент из списка, когда условие выполнено.

Комментарии:

1. Вам нужно использовать итератор для удаления элемента из списка.

Ответ №1:

Удалить элемент из базы списка при некотором условии.

 List<Integer> al = new ArrayList<>();
        al.add(605);
        al.add(260);
        al.add(306);
        al.add(7);
        al.add(6);

        Iterator itr = al.iterator();
        while (itr.hasNext()) {
            int x = (Integer) itr.next();
            if (x < 300)
                itr.remove();
        }

        System.out.println(" ArrayList : "   al);
  

Комментарии:

1. Я пытался использовать итератор точно таким же образом (с другим условием) и по-прежнему получал ошибку.

Ответ №2:

Решение 1:

Выполняя итерацию по циклу, вы пытаетесь изменить значение списка в remove() операции. Это приведет к ConcurrentModificationException .

Iterator.remove() безопасно, вы можете использовать его следующим образом:

Вот ваш код:

 public static boolean deleteItem(String callNumber, int copy) {
        for (Iterator<Item> it = itemList.iterator(); it.hasNext(); ) {
            Item rItem = it.next();
            if (rItem.getCallNumber().equals(callNumber)
                    amp;amp; rItem.getCopyNumber() == copy) {
                it.remove();
                return true;
            }
        }

        return false;

    }
  

Обратите внимание, что Iterator.remove() это единственный безопасный способ изменить коллекцию во время итерации; поведение не определено, если базовая коллекция изменяется любым другим способом во время выполнения итерации.

Ваши данные здесь:

 itemList = new ArrayList<>();

        itemList.add(new Item("0012", 1));
        itemList.add(new Item("0013", 2));
        itemList.add(new Item("0014", 3));
        itemList.add(new Item("0015", 1));


        String deletedItem="0014";
        int copy=3;
        boolean isDeleted=deleteItem(deletedItem,copy);
        System.out.println(deletedItem " deleted status :" isDeleted);

        System.out.println();

        deletedItem="0012";
        copy=1;
        isDeleted=deleteItem(deletedItem,copy);
        System.out.println(deletedItem " deleted status :" isDeleted);
  

Решение 2:

Во время итерации Arraylist вам не разрешается удалять какой-либо элемент. Если вы хотите удалить элемент во время итерации, вы можете добавить удаленный элемент во вновь созданный, ArrayList скажем,. removeList после завершения итерации вы можете удалить их все за раз.

 List<Item> removeList = new ArrayList<>();

        for (Item tempItem : itemList) {

            if (tempItem.getCopyNumber() > 1) {
                Item deleteItem = getItemForDeleteItem(tempItem.getCallNumber(), tempItem.getCopyNumber());
                removeList.add(deleteItem);
            }

        }

        if (removeList.size() > 0) {
            System.out.println("Removing Item Size :" removeList);
            itemList.removeAll(removeList);
        }
  

Здесь вы выбираете те элементы, у которых одинаковый номер > 1. Если оно допустимо, оно добавляется в removeList. После завершения итерации я удаляю весь элемент, используя itemList.removeAll(removeList);

Ваш метод получения элемента

 public static Item getItemForDeleteItem(String callNumber, int copy) {
        for (Iterator<Item> it = itemList.iterator(); it.hasNext(); ) {
            Item rItem = it.next();
            if (rItem.getCallNumber().equals(callNumber)
                    amp;amp; rItem.getCopyNumber() == copy) {
                return rItem;
            }
        }

        return null;

    }