【问题标题】:How can I remove an item from an ArrayList when it's data type is abstract?当数据类型为抽象时,如何从 ArrayList 中删除项目?
【发布时间】:2018-09-21 01:39:24
【问题描述】:

我是 Java 新手,所以如果这个问题太愚蠢或其他什么,首先很抱歉。我有一个抽象类的 ArrayList。我在列表中添加了一些对象。现在我需要通过其中一个属性找到它来删除其中一个。问题是抽象类有两个具体类,并且它们都被添加到列表中。该属性是从抽象类继承的,所以当我做一个 foreach 时,我用抽象类来做,但我不知道如何告诉它它需要删除的对象是这个具体类而不是另一个。

    public void removeFruit (Integer fruitCode) {
Apple lostFruit = null;
Banana lostFruit2 =null;
    for (Fruit fruit1 : fruitList) {
        if (fruit1.getFruitCode().equals(fruitCode) && fruit1 == Apple) {
            lostFruit = (Apple) fruit1;
            fruitList.remove(lostFruit);
        }else {
            lostFruit2 = (Banana) fruit1;
            fruitList.remove(lostFruit2);
        }

    }
    System.out.println(fruitCode + "has been removed from the list");

}

【问题讨论】:

  • 当你要查找的属性是抽象类型时,为什么要知道它是什么具体类型?

标签: java oop arraylist abstract-class


【解决方案1】:

您需要一个Iterator 来完成此操作(for-each 循环隐藏)。正如Iterator.remove() javadoc 指出的那样,如果在迭代过程中以任何方式而不是调用此方法来修改底层集合,则迭代器的行为是未指定的。

Iterator<Fruit> iter = fruitList.iterator();
while (iter.hasNext()) {
    Fruit f = iter.next();
    if (f.getFruitCode().equals(fruitCode)) {
        if (f instanceof Apple) {
            Apple a = (Apple) f;
            // ...
        } else if (f instanceof Banana) {
            Banana b = (Banana) f;
            // ...
        }
        iter.remove();
        System.out.println(fruitCode + " has been removed from the list");
    }
}

【讨论】:

  • 虽然它可能已经完成了它应该做的事情(删除对象),但它会继续运行直到它完成整个列表吗?还是会在找到对象并将其移除后停止?
  • @Nyom 它会继续下去。你没有说fruitCode 是独一无二的。如果它应该在一场比赛后停止,请添加 break
  • 很抱歉。在这种情况下,中断将出现在 if 子句中或 iter.remove(); 之后。 ? (我很少使用 while 语句,所以我不确定在这种情况下我应该在哪里打破它)
  • fruitCode 上的if 内的iter.remove 之后。此外,如果您没有对ab 做任何其他事情,您可以删除这些演员表。真的不清楚你为什么想要它们。
  • 我被告知需要强制转换,因为 foreach 使用抽象类运行,但我的结果需要是具体类
【解决方案2】:

无需投射

属性继承自抽象类

无需投射。在处理Fruit 时,我们不关心AppleBanana

如果抽象类有你需要的东西,你就不用关心具体的子类了。这就是polymorphism 的重点,当更通用的类型就足够时,不关心具体的类型。

public Fruit removeFruit (Integer fruitCode , List<Fruit> fruitList ) {

    for (Fruit fruit : fruitList ) {
        if ( fruit.getFruitCode().equals( fruitCode ) {
            fruitList.remove( fruit );
            return fruit ;
        }
    }
    return null ;  // In case you fruit code was not found.
}

示例用法:

List<Fruit> fruits = … ;
Integer fruitCode = … ;
Fruit fruitRemoved = this.removeFruit( fruitCode , fruits ) ;
System.out.println(
    "You deleted fruit code: " + fruitCode + " of type: " + fruitRemoved.getClass().getName() ;
)

您删除了水果代码:42 类型:Apple


在上面的示例中,我实际上会返回 Optional&lt;Fruit&gt; 而不是 Fruit。但那完全是另一回事了。

【讨论】:

  • 这是我最初的解决方案,但由于某种原因它没有成功,所以我尝试了另一种方法(我在这里展示的那个我无法让它运行)。我会看看我的代码中是否还有其他错误会阻止它工作,尽管所有其他事情都像他们应该做的那样
【解决方案3】:

检查fruit1是否是Apple类的实例

if (fruit1 instanceof Apple) {
// your code
}

【讨论】:

    猜你喜欢
    • 2017-11-30
    • 1970-01-01
    • 2012-05-29
    • 2014-05-17
    • 1970-01-01
    • 2016-06-15
    • 2019-10-25
    • 1970-01-01
    相关资源
    最近更新 更多