简体   繁体   中英

Java return ArrayList by type

I have a simple function that returns a specific ArrayList but I'm wondering if there is a way to return one by its type?

I have this:

ArrayList<Tile> getTiles() {
    ArrayList<Tile> tiles = new ArrayList<>();
    for (GameObj obj : gameObjs) {
        if (obj instanceof Tile)
            tiles.add((Tile) obj);
    }
    return tiles;
}

and this:

ArrayList<Obj> getObjs() {
    ArrayList<Obj> objs = new ArrayList<>();
    for (GameObj obj : gameObjs) {
        if (obj instanceof Obj)
            objs.add((Obj) obj);
    }
    return objs;
}

So I'll end up with multiple functions just to return a simple ArrayList again and again. Of course Tile , Obj etc extend GameObj . I'm wondering if there's a way to return whichever type I require. I tried this, but it doesn't work:

ArrayList<GameObj> getByType(Class<? extends GameObj> whichType) {
    ArrayList<GameObj> objs = new ArrayList<>();
    for (GameObj obj : gameObjs) {
        if (obj.getClass() == whichType)
            objs.add(obj);
    }
    return objs;
}

ArrayList<Tile> tiles = (ArrayList<Tile>) getByType(Tile.class);

I get the error Cannot cast from ArrayList<GameObj> to ArrayList<Tile>

I commented the part that you need, comment in/out the other respective line, you'll see the difference in the results.

package stackoverflow;

import java.util.ArrayList;

public class ReturnListByType {



    public static void main(final String[] args) {
        final ArrayList<Object> mixedList = new ArrayList<>();
        mixedList.add("Hello!");
        mixedList.add(Double.valueOf(453.453));
        mixedList.add(Integer.valueOf(423));
        mixedList.add("World");

        {
            System.out.println("Strings:");
            final ArrayList<String> list = filterList(mixedList, String.class);
            for (final String i : list) {
                System.out.print(i + "\t");
            }
            System.out.println("\n");
        }
        {
            System.out.println("Integers:");
            final ArrayList<Integer> list = filterList(mixedList, Integer.class);
            for (final Integer i : list) {
                System.out.print(i + "\t");
            }
            System.out.println("\n");
        }
        {
            System.out.println("Doubles:");
            final ArrayList<Double> list = filterList(mixedList, Double.class);
            for (final Double i : list) {
                System.out.print(i + "\t");
            }
            System.out.println("\n");
        }
        {
            System.out.println("Numbers:");
            final ArrayList<Number> list = filterList(mixedList, Number.class);
            for (final Number i : list) {
                System.out.print(i + "\t");
            }
            System.out.println("\n");
        }
    }

    static public <T> ArrayList<T> filterList(final Iterable<Object> pItems, final Class<T> pClass) {
        final ArrayList<T> ret = new ArrayList<>();
        for (final Object o : pItems) {
            //          if (o.getClass().isAssignableFrom(pClass)) ret.add((T) o); // either use this line, direct and parents match
            if (pClass.isAssignableFrom(o.getClass())) ret.add((T) o); // or this line, direct and child match
        }
        return ret;
    }



}

Update

You could also limit the type parameter T to something like static public <T extends GameObj> ArrayList<T> filterList(final Iterable<Object> pItems, final Class<T> pClass) { if you need that.

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