Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Types by argument?

I'm wondering if is possible pass types by argument in Java.

Let me explain better:

Suppose the next code

class Bee {
    // Class implementation
}

class Worker extends Bee {
    // Class implementation
}


class Queen extends Bee {
    // Class implementation
}

And now create a container with my bees objects

Vector<Bee> x=new Vector<Bee>();
// ...
for(i=0;i<10;i++)
    x.add(new Worker());
// ...
for(i=0;i<10;i++)
    x.add(new Queen());

Now I want create a generic method that iterates the vector and returns a set with a specific type of bees, Worker or Queen. How to do this?

EDIT

I tried

search(x,Worker.class);

static public <T extends Bee> Set<T> search(List<Bee> bees, Class<T> clazz){
    // ...
}

and I got an error reporting "The method search(List, Class) is no applicable for the arguments (Set, Class)". The problem is on 2nd argument because the types are incompatible.

like image 856
rigon Avatar asked May 10 '26 07:05

rigon


2 Answers

From your edit I see, you're still struggling with the implementation. Here is a working example:

public static void main(String[] args) {
    Collection<Bee> bees = new ArrayList<Bee>();
    bees.add(new Hive.Worker());
    bees.add(new Hive.Queen());
    Set<Queen> queens = getBeesOfOneType(bees, Queen.class);
}

private static <T extends Bee> Set<T> getBeesOfOneType(Collection<Bee> bees, Class<T> beeType) {
    Set<T> result = new HashSet<T>();
    for (Bee bee : bees) {
        if (beeType.isInstance(bee)) {
            // The following cast is safe. The previous if makes sure that
            // that bee can be cast to T at this place
            T beeTypeInstance = beeType.cast(bee);
            result.add(beeTypeInstance);
        }
    }
    return result;
}

There is still one Type safety warning and I'm pretty sure that this one can't be eliminated. The compiler doesn't now, that we select only the T type bees, so it has to warn us.

like image 165
Andreas Dolk Avatar answered May 12 '26 20:05

Andreas Dolk


You can use instanceof expression to test if a Bee is a Worker or a Queen. You can use this to filter your Vector<Bee> (or even better, a List<Bee>) according to the subtypes.

Guava also provides Iterables.filter(Iterable<?> unfiltered, Class<T> type) that you can use.

like image 34
polygenelubricants Avatar answered May 12 '26 19:05

polygenelubricants



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!