简体   繁体   中英

Generic Types and Instanceof

Let's set up a few hypothetical classes

class Animal {

}

class Dog extends Animal {

}

class Cat extends Animal {

}

class Rat extends Animal {

}

How would I go about doing something like this?

List<Animal> listOfAnimals = ArrayList<Animal>();
listOfAnimals.add(new Dog);
listOfAnimals.add(new Cat);
listOfAnimals.add(new Rat);
listOfAnimals.add(new Rat);

//Return a list of animals that are the type of T
public <T> ArrayList<T> animalsOfType(T animal) {
    for (Animal A : listOfAnimals) {
        if (A instanceof T) {
            //The current animal in the list is the type of T
        }
    }
}

This code would thus let me do this

//Returns a list of all dogs from the current list of animals
List<Dog> currentListOfDogs = animalsOfType(Dog);

I've seen a couple other SO pages referencing this and that it isn't possible, but I don't really understand the workaround that they're suggesting (such as what's referenced here ). Is this possible, and how exactly would I have to restructure my classes in order to achieve a result like this?

Thanks in advance!

I'm not sure this is what you want.

public static void main(String[] args) {

    List<Animal> listOfAnimals = new ArrayList<>();
    listOfAnimals.add(new Dog());
    listOfAnimals.add(new Cat());
    listOfAnimals.add(new Rat());
    listOfAnimals.add(new Rat());

    List<Dog> result = animalsOfType(Dog.class, listOfAnimals);

}

public static <T> ArrayList<T> animalsOfType(Class<T> animal, List<Animal> listOfAnimals) {
    ArrayList<T> list = new ArrayList<>();
    for (Animal A : listOfAnimals) {
        if (animal.isInstance(A)) {
            list.add((T) A);
        }
    }
    return list;
}

Try This

public <T extends Animal> List<T> animalsOfType(Class<T> animalClazz) {
    return listOfAnimals.stream().filter(animal -> clazz.isInstance(animal)).map(animal -> (T) animal).collect(Collectors.toList());
}

Its a simple java 8 solution:

public static <T extends Animal> List<T> animalsOfType(Class<T> animalClass, List<Animal> listOfAnimals) {
    return listOfAnimals.stream().filter(a -> a instanceof animalClass).collect(Collectors.toList());
}

and than you will call:

List<Dog> currentListOfDogs = animalsOfType(Dog.class, listOfAnimals);

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