通过迭代器从ArrayList中删除对象

时间:2020-03-10 17:23:37

标签: java arraylist iterator

我想创建一个类似于家庭预算的程序,所以我有一个AmountModel类 (我知道Integer的id不太好,但是现在不成问题了):

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;
}

添加对象效果很好,但是当我尝试使用delete方法时,我必须放置第一个索引。

示例:
我有三个对象(索引分别为0、1、2)。

  • 当我选择1或2个程序时,什么也不做。
  • 当我选择0时,程序将删除第一个索引,而保留索引1和2。
  • 当我选择2时,程序什么也不做。
  • 当我选择1时,程序将删除索引1,保留索引2 ...等等。

此方法有什么问题?

4 个答案:

答案 0 :(得分:1)

您应该将输入逻辑与删除逻辑分开,并接受列表作为参数。

注意:这仅适用于可变列表。如果您使用类似Arrays.asList()的方法,则会引发异常。

public void deleteAmount(List<AmountModel> list, int key) {
    list.removeIf(a -> a.getId().equals(key));
}

答案 1 :(得分:1)

欢迎堆栈溢出!

正如其他人所提到的,有几种解决方法。但是我认为您可以通过更改用于访问AmountModel集合的数据结构来简化此操作:如果您经常通过ID访问某项,那么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
}

希望这会有所帮助!如果您有兴趣,我将根据here的要点汇总一个工作示例。 (在Groovy中,但足以让您知道这个想法)

答案 2 :(得分:0)

您的break语句仅在第一次迭代中中断while循环。因此,仅当第一个am.getId()与您的拳头输入匹配时,它才有效。 同样,您的sc.nextInt()将继续扫描下一个可用的输入,将其从while循环中删除。

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;
}

答案 3 :(得分:-1)

在循环外调用sc.nextInt(),否则它将在每次循环返回时运行,因为每次循环结束时都会重新评估条件。 您也可以使用列表的删除方法

    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;
    }
相关问题