Generics question

K

kelvSYC

Suppose I have a class Foo, which has subclasses Foo1 and Foo2. Now,
suppose I need a map whose key type is Class<T extends Foo> and whose
value type is Set<T> (that is, if the key type is Foo1.class, then the
value type is Set<Foo1>).

Is it even possible to declare such a type using generics or do I have
to do something in a roundabout way?
 
M

Mark Space

kelvSYC said:
Suppose I have a class Foo, which has subclasses Foo1 and Foo2. Now,
suppose I need a map whose key type is Class<T extends Foo> and whose
value type is Set<T> (that is, if the key type is Foo1.class, then the
value type is Set<Foo1>).

Is it even possible to declare such a type using generics or do I have
to do something in a roundabout way?


I think so, give a certain assumptions about what you really want. Try
this method:

public static <X extends Foo> Map<Class<X>,Set<X>> getFooMap() {
return new HashMap<Class<X>,Set<X>>();
}

It's somewhat roundabout, although not too much I think. Then you can
do the following. The last line below is a compile time error.

Map<Class<Foo>,Set<Foo>> foos = getFooMap();
Map<Class<Foo1>,Set<Foo1>> foos1 = getFooMap();
Map<Class<Foo2>,Set<Foo2>> foos2 = getFooMap();
Map<Class<Foo1>,Set<Foo2>> foosX = getFooMap(); // oops
 
L

Lew

I couldn't find a way to declare it directly.

Mark said:
I think so, give a certain assumptions about what you really want. Try
this method:

public static <X extends Foo> Map<Class<X>,Set<X>> getFooMap() {
return new HashMap<Class<X>,Set<X>>();
}

It's somewhat roundabout, although not too much I think. Then you can
do the following. The last line below is a compile time error.

Map<Class<Foo>,Set<Foo>> foos = getFooMap();
Map<Class<Foo1>,Set<Foo1>> foos1 = getFooMap();
Map<Class<Foo2>,Set<Foo2>> foos2 = getFooMap();
Map<Class<Foo1>,Set<Foo2>> foosX = getFooMap(); // oops

I came up with the same kind of method and a holder/factory class idiom:

package testit;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Generitor <T extends Foo>
{
private Map <Class <T>, Set <T>> generators =
new HashMap <Class <T>, Set <T>> ();

public static <F extends Foo> Map <Class <F>, Set <F>>
makeGenerators()
{
return new HashMap <Class <F>, Set <F>> ();
}

public Map <Class <T>, Set <T>> getGenerators()
{
return this.generators;
}

public Map <Class <T>, Set <T>> newGenerators()
{
return new HashMap <Class <T>, Set <T>> ();
}
}
 
K

kelvSYC

Piotr Kobzda said:
How useful a map instance like this could be?

To me it's useless, because it allows for mapping of only one key, i.e.
of Foo1.class (singleton of Class<Foo1> type). Do you think the OP is
looking for that?

I think the OP is trying to map multiple types T (a subclass of Foo
each) to the set of instances of that same type, i.e. for each key of
type T there is associated value of type Set<T> in the map. That makes
sense to me. But, of course, I may be wrong.

Yeah, I was trying to map a class object with a set of instances of
that class. To be more precise, suppose we have these:

class A;
class B extends A;
class C extends A;

Set<B> bset;
Set<C> cset;

I was hoping to have a way to have a Set<A> for which you could easily
retrieve the subset of Bs, for example, while having the fact that
changing the subset also changed the original set.
 
D

Daniel Pitts

kelvSYC said:
Suppose I have a class Foo, which has subclasses Foo1 and Foo2. Now,
suppose I need a map whose key type is Class<T extends Foo> and whose
value type is Set<T> (that is, if the key type is Foo1.class, then the
value type is Set<Foo1>).

Is it even possible to declare such a type using generics or do I have
to do something in a roundabout way?
Unfortunately, it is not possible to do this with generics.

You *can* write your own wrapper class

class FoosMap {
Map<Class, Set> map = new HashMap<Class, Set>;

public <T> void add(Class<T> type, T value) {
Set<T> set = get(type);
if (set == null) {
set = new HashSet<T>();
map.put(type, set);
}
set.add(value);
}

public <T> Set<T> get(Class<T> type) {
return (Set<T>) map.get(type);
}
}
 
M

Mark Space

Piotr said:
How useful a map instance like this could be?

To me it's useless, because it allows for mapping of only one key, i.e.
of Foo1.class (singleton of Class<Foo1> type). Do you think the OP is
looking for that?


I think you're correct. I did that example quickly. I think generic
methods are the right answer, as your example showed, but this one
probably doesn't express the OP's intended semantics.
 
D

Daniel Pitts

Piotr said:
More precisely -- it is possible to declare such a type (see my earlier
posting), but generics will not prevent the OP from undesired usage of it.


Use of the raw types should be avoided -- they are available in Java
just for backward compatibility, and possibly will be removed from the
language in the future.

What's wrong with using wildcards here?
I suppose you could use Class<?> and Set<?> instead.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

can this be done with generics? 32
generics puzzle 57
Generics 12
Generics 24
What is the most astounding C++ syntax construct? 0
Hairy generics question 29
Generics ? 14
How do I fix this typescript error? 0

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top