简体   繁体   中英

Iterating through ArrayList and returning an ArrayList of the objects that meet an instanceof check

I'm having a problem with class types. I have a super class "Edible" and an interface "Colorful". Not all edible items are colorful so colorful is only implemented on certain Edible objects. I'm trying to take an ArrayList of Edible items, loop through it, and return a new ArrayList that contains only the colorful ones. The error I'm receiving now is

"The method add(Colorful) in the type ArrayList is not applicable for the arguments (Edible)"

How can I get around this restriction?

private ArrayList<Edible> elist;
private ArrayList<Colorful> clist;

public List<Colorful> getColorfulItems(){
    for(Edible x : elist)
        if(x instanceof Colorful){
            clist.add(x);
        }
    return clist;

    }

You need to typecast your Edible to Colorful : -

if(x instanceof Colorful){
        clist.add((Colorful)x);
}

Or, if you want to avoid typecase, declare your ArrayList with WildCard : -

private ArrayList<? extends Colorful> clist;

By declaring your ArrayList like this, you can add anything that is a subtype of Colorful without typecasting

Also, you don't need to return your modified list everytime, since your list is declared as instance variable . So the change will be reflected in the list, without returning the list.

Change your list to accept any object of type Colorful . Read Generics, Inheritance, and Subtypes to understand more.

Example:

private ArrayList<? extends Colorful> clist;

I would resist using fields as return values. In this case, the list will grow every time you call the method which is likely to be undesirable.

You can make the method more generic with

@SuppressWarnings("unchecked")
public <T> List<T> selectItems(Class<T> clazz) {
    List<T> ret = new ArrayList<T>();
    for (Edible x : elist)
        if (clazz.isInstance(x))
            ret.add((T) x);
    return ret;
}

which can be used to select different types.

List<Serializable> serializableList = x.selectItems(Serializable.class);
List<Colorful> colorfulList = x.selectItems(Colorful.class);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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