简体   繁体   English

当数据类型为抽象时,如何从ArrayList中删除项目?

[英]How can I remove an item from an ArrayList when it's data type is abstract?

I'm new to Java so first of all sorry if this question is too stupid or something. 我是Java的新手,所以首先很抱歉,如果这个问题太愚蠢或其他问题。 I have an ArrayList of an abstract class. 我有一个抽象类的ArrayList。 I added a few objects to the list. 我在列表中添加了一些对象。 Now I need to remove one of them by finding it by one of its attributes. 现在,我需要通过其属性之一找到它来删除其中之一。 The thing is that the abstract class has two concrete classes and both of them were added to the list. 问题是抽象类有两个具体的类,并且它们都已添加到列表中。 The attribute is inherited from the abstract class so when I do a foreach I do it with the abstract class, but I don't know how to tell it that the object it needs to remove is this concrete class and not the other one. 该属性是从抽象类继承的,因此当我进行一次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");

}

You need an Iterator to accomplish that (which the for-each loop hides ). 您需要一个Iterator来完成该任务( for-each循环将其隐藏了 )。 As the Iterator.remove() javadoc notes the behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method. 正如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");
    }
}

No need to cast 无需投放

The attribute is inherited from the abstract class 该属性是从抽象类继承的

No need to cast. 无需投放。 When handling a Fruit , we do not care about Apple or Banana . 处理Fruit ,我们不在乎AppleBanana

If the abstract class has what you need, you do not care about the concrete subclass. 如果抽象类具有所需的内容,则无需关心具体的子类。 That is the point of polymorphism , not caring about the specific types when the more general type suffices. 这就是多态性的意义 ,当更通用的类型足够时,不在乎特定的类型。

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

Example usage: 用法示例:

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

You deleted fruit code: 42 of type: Apple 您删除了水果代码:42类型:苹果


In the example above, I would actually return Optional<Fruit> rather than Fruit . 在上面的示例中,我实际上将返回Optional<Fruit>而不是Fruit But that is a whole other discussion. 但这是另一回事。

Check if fruit1 is instance of class Apple 检查fruit1是否为Apple类的实例

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

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

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