A question about generics

Discussion in 'Java' started by Lemon Tree, Nov 2, 2005.

  1. Lemon Tree

    Lemon Tree Guest

    Hello,

    I am wondering what is the most elegant (and correct) way to organize
    the following type hierarchy.

    Let's suppose to have the following parametric class:

    class Foo<T extends InfoType> {
    private T info;
    ...
    public T getInfo() {
    ...
    }
    }

    Let's now suppose that we want to create a Container for Foo instances,
    and that we want to be able to search that container by using the info
    contained in every Foo instance.

    I might do the following:

    class FooCollection<T extends Foo> extends HashSet<T> {
    ...
    public T findByInfo(InfoType info) {
    for(T t : this) {
    if(t.getInfo().compareTo(info) == 0) {
    return t;
    }
    }
    return null;
    }

    Obviously the InfoType class contains an int compareTo(Bar info) method
    for comparing InfoType (and their subclasses)

    The previous code is correct but generates some warnings with respect
    to the fact that the type parameter T is of type Foo and Foo is a
    parametric type which is not instantiated with respect to its type
    parameter.

    In order to avoid the warnings I might do the following:

    class FooCollection<T extends InfoType> extends HashSet<Foo<T>> {
    ...
    public Foo<T> findByInfo(T info) {
    ...
    }
    }

    This solution eliminates the warnings but I do not like it because when
    I declare a FooCollection<InfoType>, by reading the declaration, it is
    not clear that I am actually instantiating a collection of
    Foo<InfoType> objects but it gives the impression that I am dealing
    with a InfoType collection.

    The third solution is to make explicit both the InfoType and the Foo
    instances contained in the collection:

    class FooCollection<T extends InfoType, S extends Foo<T>> extends
    HashSet<S> {
    ...
    public S findByInfo(T info) {
    ...
    }
    }

    This also works, but when I have to declare a FooCollection I need to
    do:
    FooCollection<MyInfoType, Foo<MyInfoType>> which is a bit redundant and
    unclear.

    I do not see any other solution to how to structure the hierarchy.

    In my opinion the most elegant and simple solution is the first one.
    But I would like to get rid of the warnings. Do you know how to do
    this? Can you suggest another more elegant solution (if it exists?)

    Thank you
    Lemon Tree, Nov 2, 2005
    #1
    1. Advertising

  2. Lemon Tree

    zero Guest

    "Lemon Tree" <> wrote in
    news::

    > Hello,
    >
    > I am wondering what is the most elegant (and correct) way to organize
    > the following type hierarchy.
    >
    > Let's suppose to have the following parametric class:
    >
    > class Foo<T extends InfoType> {
    > private T info;
    > ...
    > public T getInfo() {
    > ...
    > }
    > }
    >
    > Let's now suppose that we want to create a Container for Foo
    > instances, and that we want to be able to search that container by
    > using the info contained in every Foo instance.
    >
    > I might do the following:
    >
    > class FooCollection<T extends Foo> extends HashSet<T> {
    > ...
    > public T findByInfo(InfoType info) {
    > for(T t : this) {
    > if(t.getInfo().compareTo(info) == 0) {
    > return t;
    > }
    > }
    > return null;
    > }
    >
    > Obviously the InfoType class contains an int compareTo(Bar info)
    > method for comparing InfoType (and their subclasses)
    >
    > The previous code is correct but generates some warnings with respect
    > to the fact that the type parameter T is of type Foo and Foo is a
    > parametric type which is not instantiated with respect to its type
    > parameter.
    >


    <snipped>

    I don't see the problem with your first version. If you instantiate a
    FooCollection with FooCollection<Foo<InfoType>> col = new
    FooCollection<Foo<InfoType>>();
    you should not get any warnings. And it
    is very clear that you are dealing with a collection of Foo objects -
    and more specifically Foo<InfoType> objects.
    zero, Nov 2, 2005
    #2
    1. Advertising

  3. Lemon Tree

    Lemon Tree Guest

    > <snipped>
    >
    > I don't see the problem with your first version. If you instantiate a
    > FooCollection with FooCollection<Foo<InfoType>> col = new
    > FooCollection<Foo<InfoType>>();
    > you should not get any warnings. And it
    > is very clear that you are dealing with a collection of Foo objects -
    > and more specifically Foo<InfoType> objects.
    >

    It gives me a warning in the definition of the findByInfo method:

    Type safety: The method getInfo() belongs to the raw type Foo.
    References
    to generic type Foo<T> should be parameterized

    That's what I would like to remove.
    But I am starting to think that it is not possible.
    Lemon Tree, Nov 2, 2005
    #3
  4. Hi,

    Lemon Tree wrote:
    > Hello,
    >
    > class Foo<T extends InfoType> {
    > private T info;
    > ...
    > public T getInfo() {
    > ...
    > }
    > }


    I think, this is the (only) "correct" solution:

    > class FooCollection<T extends InfoType> extends HashSet<Foo<T>> {
    > ...
    > public Foo<T> findByInfo(T info) {
    > ...
    > }
    > }
    >
    > This solution eliminates the warnings but I do not like it because when
    > I declare a FooCollection<InfoType>, by reading the declaration, it is
    > not clear that I am actually instantiating a collection of
    > Foo<InfoType> objects but it gives the impression that I am dealing
    > with a InfoType collection.


    Perhaps you can rename the classes, so that it becomes more obvious?
    (Perhaps simply "CollectionFoo<InfoType>" or (IMHO not so good)
    "CollectionOfFooOf<InfoType>")

    Ciao,
    Ingo
    Ingo R. Homann, Nov 2, 2005
    #4
  5. Lemon Tree

    zero Guest

    "Lemon Tree" <> wrote in
    news::

    >> <snipped>
    >>
    >> I don't see the problem with your first version. If you instantiate
    >> a FooCollection with FooCollection<Foo<InfoType>> col = new
    >> FooCollection<Foo<InfoType>>();
    >> you should not get any warnings. And it
    >> is very clear that you are dealing with a collection of Foo objects -
    >> and more specifically Foo<InfoType> objects.
    >>

    > It gives me a warning in the definition of the findByInfo method:
    >
    > Type safety: The method getInfo() belongs to the raw type Foo.
    > References
    > to generic type Foo<T> should be parameterized
    >
    > That's what I would like to remove.
    > But I am starting to think that it is not possible.
    >
    >


    The following quick test compiled without warnings for me.

    Alternatively, have you tried

    class FooCollection<T extends Foo<?>> extends HashSet<T>

    This will tell the compiler you want a FooCollection of any type of Foo,
    and you don't care which type - but this is still type-checked, unlike
    the raw Foo in <T extends Foo>.


    -- test code --

    import java.util.HashSet;

    public class GenericsTest
    {
    public static void main(String args[])
    {
    new GenericsTest();
    }

    public GenericsTest()
    {
    FooCollection<Foo<InfoType>> col = new FooCollection<Foo<InfoType>>();
    }

    private class InfoType implements Comparable<InfoType>
    {
    public int compareTo(InfoType i)
    {
    return 0;
    }
    }

    private class Foo<T extends InfoType>
    {
    private T info;
    public T getInfo()
    {
    return info;
    }
    }

    private class FooCollection<T extends Foo> extends HashSet<T>
    {
    public T findByInfo(InfoType info)
    {
    for(T t : this)
    {
    if(t.getInfo().compareTo(info) == 0)
    {
    return t;
    }
    }
    return null;
    }
    }
    }
    zero, Nov 2, 2005
    #5
  6. Lemon Tree

    Lemon Tree Guest

    zero ha scritto:

    > The following quick test compiled without warnings for me.
    >

    Your code works without any warning.
    I was suprised because your code is basically identical to mine (the
    one which generated the warnings). But when I tried to split your code
    in several files (a class per file) the warning appeared again!

    I don't know why. It would be interesting to know.

    > Alternatively, have you tried
    > class FooCollection<T extends Foo<?>> extends HashSet<T>
    >

    Bingo!
    That works even in the "splitted" layout.

    Thank you for your help.

    > This will tell the compiler you want a FooCollection of any type of Foo,
    > and you don't care which type - but this is still type-checked, unlike
    > the raw Foo in <T extends Foo>.
    >

    Yes. That's what I missed before :)

    Thank you again
    Lemon Tree, Nov 2, 2005
    #6
  7. Lemon Tree

    zero Guest

    "Lemon Tree" <> wrote in news:1130948806.773789.264120
    @g44g2000cwa.googlegroups.com:

    >
    > zero ha scritto:
    >
    >> The following quick test compiled without warnings for me.
    >>

    > Your code works without any warning.
    > I was suprised because your code is basically identical to mine (the
    > one which generated the warnings). But when I tried to split your code
    > in several files (a class per file) the warning appeared again!
    >
    > I don't know why. It would be interesting to know.
    >


    That is indeed surprising. I can't think of a reason that may be. Maybe
    someone else here has an idea?

    >> Alternatively, have you tried
    >> class FooCollection<T extends Foo<?>> extends HashSet<T>
    >>

    > Bingo!
    > That works even in the "splitted" layout.
    >
    > Thank you for your help.
    >
    >> This will tell the compiler you want a FooCollection of any type of Foo,
    >> and you don't care which type - but this is still type-checked, unlike
    >> the raw Foo in <T extends Foo>.
    >>

    > Yes. That's what I missed before :)
    >
    > Thank you again
    >


    My pleasure
    zero, Nov 2, 2005
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. geoffrey wall

    question on generics, constants in vhdl

    geoffrey wall, Oct 1, 2005, in forum: VHDL
    Replies:
    1
    Views:
    632
    Mike Treseler
    Oct 1, 2005
  2. Roger Levy
    Replies:
    20
    Views:
    878
    Neal Gafter
    Jan 5, 2005
  3. Joona I Palaste

    Generics question

    Joona I Palaste, Oct 14, 2004, in forum: Java
    Replies:
    6
    Views:
    463
    Vincent Cantin
    Oct 15, 2004
  4. Juergen Berchtel
    Replies:
    1
    Views:
    5,968
    John C. Bollinger
    May 20, 2005
  5. Soul
    Replies:
    0
    Views:
    503
Loading...

Share This Page