Удалить объект из ArrayList с помощью итератора - PullRequest
0 голосов
/ 10 марта 2020

Я хочу создать программу, которая бы походила на домашний бюджет, поэтому у меня есть класс AmountModel (я знаю, что Integer не очень хорош для идентификатора, но сейчас это не проблема):

import java.time.LocalDate;

public class AmountModel {
  private Integer id;
  private Double amount;
  private CategoryModel categoryModel;
  private LocalDate localDate;

  // getters/setters etc.
}

И в другом классе я построил этот метод deleteAmount:

static Scanner sc = new Scanner(System.in);

public List<amountModel> deleteAmount() {
    Iterator<AmountModel> it = amountList.iterator();
    while (it.hasNext()) { 
        System.out.println("Choose index to delete ");
        AmountModel am = it.next();
        if (am.getId().equals(sc.nextInt())) {
            it.remove();
        }
        break;
    }
    return amountList;
}

Добавление объекта работает хорошо, но когда я пытаюсь использовать метод удаления, я должен поставить первый индекс.

Пример:
У меня есть три объекта (с индексом 0, 1, 2).

  • Когда я выбираю 1 или 2, программа ничего не делает.
  • Когда я выбрав 0, программа удаляет первый индекс, остается индекс 1 и 2.
  • Когда я выбираю 2, программа ничего не делает.
  • Когда я выбираю 1, программа удаляет индекс 1, остается индекс 2 ... et c.

Что не так с этим методом?

Ответы [ 4 ]

1 голос
/ 10 марта 2020

Добро пожаловать в переполнение стека!

Как уже упоминалось, есть несколько способов справиться с этим. Но я думаю, что вы можете сделать это еще проще, изменив структуру данных, используемую для доступа к вашей коллекции AmountModel: если вы часто обращаетесь к элементу по идентификатору, Map отлично подойдет.

Больше не нужно беспокоиться о состоянии итератора; Вы можете просто сделать что-то вроде:

// Map "amounts" by ID for easy O(1) lookup.
static Map<Integer, AmountModel> amountMap

public void deleteAmount(Integer id) {
  if (!amountMap.containsKey(id)) { 
    // (TODO: Handle invalid input)
    throw new Exception()
  }

  amountMap.remove(id)
  return
}

Надеюсь, это поможет! Я собрал рабочий пример в суть здесь , если вам интересно. (В Groovy, но должно быть достаточно, чтобы дать вам идею)

1 голос
/ 10 марта 2020

Вы должны отделить свои входные логи c от ваших логинов удаления c и принять список в качестве параметра.

Примечание: это работает только с изменяемым списком. Если вы используете что-то вроде Arrays.asList (), оно выдаст исключение.

public void deleteAmount(List<AmountModel> list, int key) {
    list.removeIf(a -> a.getId().equals(key));
}
0 голосов
/ 10 марта 2020

Ваш оператор break прерывает время l oop только в первой итерации. Таким образом, это будет работать, только если первый am.getId () совпадает с вашим вводом кулака. Кроме того, ваш s c .nextInt () продолжит сканирование для поиска следующего доступного ввода. Удалите его, пока l oop.

static Scanner sc = new Scanner(System.in);
public List<AmoutModel> deleteAmount() {
    Iterator<AmoutModel> it = amountList.iterator();
    Integer scId = sc.nextInt();
    while (it.hasNext()) { 
        System.out.println("Choose index to delete ");
        AmoutModel am = it.next();
        if (am.getId().equals(scId)) {
            it.remove();
            break;
        }
    }
    return amountList;
}
0 голосов
/ 10 марта 2020

вызывает ваш s c .nextInt () вне l oop, в противном случае он будет запускаться каждый раз, когда возвращается l oop, поскольку условие переоценивается каждый раз, когда заканчивается l oop. также вы можете использовать метод удаления списка

    static Scanner sc = new Scanner(System.in);
    public List<AmoutModel> deleteAmount() {
        System.out.println("Choose index to delete ");
        int index = sc.nextInt();
        amountList.remove(index);
        return amountList;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...