繁体   English   中英

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

[英]Delete an object from ArrayList by 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;
}

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

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

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

这种方法有什么问题?

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

注意:这只适用于可变列表。 如果你使用像 Arrays.asList() 这样的东西,它会抛出一个异常。

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

欢迎使用堆栈溢出!

正如其他人所提到的,有几种方法可以解决这个问题。 但我认为您可以通过更改用于访问您的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
}

希望这可以帮助! 如果您有兴趣,我在这里汇总了一个工作示例。 (在 Groovy 中,但应该足以给你这个想法)

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

在循环外调用 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;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM