• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Question for Wildcards in Collection

 
Ranch Hand
Posts: 113
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Collection<?> c = new ArrayList<String>();
....//line 1

Which line inserted independtly at line 1 will allow to compile?

a)c.add(new Object());

b)c.add("Java");

c)c.add(null);

d)All 3 lines above inserted independtely will allow to compile

e)All 3 lines above inserted independtely will not allow to compile

Answer c)

a)-->we don�t know what the element type c will be,So we cannot add Object to it.

b)-->we don�t know what the element type c will be,So we cannot add String to it.

c)-->null is allowed because it is member of every type.

d)-->Because of option a & b, d also wrong.

e)-->Because of option c, e also wrong.

-----------------------------------------------------
Actually, when I tried in the JVM, I got a) and b) cannot be compiled.
c) is fine.

Can you explain for me?
 
Ranch Hand
Posts: 114
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Collection<?> c = new ArrayList<String>();

when we use a wild card operator, we tell the compiler that we wont be adding anything to the list. And also that this collection reference can accept any type of collection.

Hence when you try to add an Object or a String you get an error
You will not get an error when adding null because null is well.. null !!

null does not belong to any specific type.

hope this clears your doubt
 
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sam,

Try this code:

ArrayList<? super String> alist = new ArrayList<String>();

//Now alist reference variable can hold any ArrayList that is parameterized with String or superclass of String, (ofcourse Object class). But the upper bound is String so only and only you are allowed to "add" String object in the list.

alist.add("a");
alist.add(new String("bb");

Thanks and Regards,
cmbhatt
 
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Collection<?> c = new ArrayList<String>();

In this statement, <?> on the left side means this collection can hold anything...(Object or any subtype)
and <String> on the right means that it can hold only strings.. Am I right?

So, what does this complete statement means..
Collection<?> c = new ArrayList<String>();

Please explain.

Thanks..
 
Chandra Bhatt
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Posted By Lovleen Gupta


Collection<?> c = new ArrayList<String>();

In this statement, <?> on the left side means this collection can hold anything...(Object or any subtype)
and <String> on the right means that it can hold only strings.. Am I right?

So, what does this complete statement means..
Collection<?> c = new ArrayList<String>();

Please explain.



Hi Guptajee,

Collection<?> c = new ArrayList<String>();

Collection is on the top of the interface heirarchy so you are availing polymorphism on base type as the term mostly used in K&B book.
Collection and ArrayList are base type so you are able to use Collection reference variable to hold the reference of ArrayList. ArrayList implements List that extends Collection.

Now come to the original issue:
wildcard <?> means unknown type, it can be Object, Animal, String, Dog, Poodle, String, StringBuffer or so.

Always keep in mind when we talk about what the reference variable can hold is not what about what objects we can add using the reference variable in collection.

Collection<?> means it can hold any collection object parameterized with any type (that is not known to us for now).

Collection<?> mycol =null;

mycol = new ArrayList<String>(); /*mycol refers to ArrayList paramerized with String */

mycol = new LinkedList<Animal>(); /*mycol refers to LinkedList paramerized with Animal */

mycol = new Vector<Double>(); /*mycol refers to Vector paramerized with Double */

Restriction What you can't do in the case of <?> (unknow type) is to add any object to it except null (ofcourse null is not object and it can be substituted to any object)

mycol.add(null); //OK
mycol.add("hello"); //NO NO
mycol.add(120.43); //NO NO
mycol.add(new Animal()); //NO NO

One should not confuse with that the reference variable can hold, with what can be added to the collection.

When we are allowed to add :

Collection<? super Dog> mycol = null; //mycol can only hold the reference of any collection that implements Collection, ofcourse and parameterized with Dog or superclass of Dog, nothing else
mycol = new ArrayList<Dog>(); //OK
mycol = new ArrayList<Animal>(); //OK
mycol = new ArrayList<Object>(); //OK, Object class is Daddy of all classes

mycol = new ArrayList<Poodle>(); //NO NO NO

What can we add to this collection:
mycol.add(new Dog()); //Good
mycol.add(new Poodle()); //Good
mycol.add(new Animal()); //No no, if your mind asks why can't we add //Animal? goto top and read from the scratch;
//otherwise you are in good shape


Hope this helps you? Do I miss anything?

Thanks and Regards,
cmbhatt
 
Lovleen Gupta
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Chandra Bhatt:
Posted By Lovleen Gupta


Hi Guptajee,

Collection<?> c = new ArrayList<String>();

Collection is on the top of the interface heirarchy so you are availing polymorphism on base type as the term mostly used in K&B book.
Collection and ArrayList are base type so you are able to use Collection reference variable to hold the reference of ArrayList. ArrayList implements List that extends Collection.

Now come to the original issue:
wildcard <?> means unknown type, it can be Object, Animal, String, Dog, Poodle, String, StringBuffer or so.

Always keep in mind when we talk about what the reference variable can hold is not what about what objects we can add using the reference variable in collection.

Collection<?> means it can hold any collection object parameterized with any type (that is not known to us for now).

Collection<?> mycol =null;

mycol = new ArrayList<String>(); /*mycol refers to ArrayList paramerized with String */

mycol = new LinkedList<Animal>(); /*mycol refers to LinkedList paramerized with Animal */

mycol = new Vector<Double>(); /*mycol refers to Vector paramerized with Double */

Restriction What you can't do in the case of <?> (unknow type) is to add any object to it except null (ofcourse null is not object and it can be substituted to any object)

mycol.add(null); //OK
mycol.add("hello"); //NO NO
mycol.add(120.43); //NO NO
mycol.add(new Animal()); //NO NO

One should not confuse with that the reference variable can hold, with what can be added to the collection.

When we are allowed to add :

Collection<? super Dog> mycol = null; //mycol can only hold the reference of any collection that implements Collection, ofcourse and parameterized with Dog or superclass of Dog, nothing else
mycol = new ArrayList<Dog>(); //OK
mycol = new ArrayList<Animal>(); //OK
mycol = new ArrayList<Object>(); //OK, Object class is Daddy of all classes

mycol = new ArrayList<Poodle>(); //NO NO NO

What can we add to this collection:
mycol.add(new Dog()); //Good
mycol.add(new Poodle()); //Good
mycol.add(new Animal()); //No no, if your mind asks why can't we add //Animal? goto top and read from the scratch;
//otherwise you are in good shape


Hope this helps you? Do I miss anything?

Thanks and Regards,
cmbhatt



Thanks Chandra,

I am good with what a reference variable can hold but am still confused with what you can add to it.
I guess, K&B also doesn't go much into add() method except saying that in wildcards can't add anything to it because of the fear that you may add something wrong to it. Though, it does say that when using the keyword super , you may be able to add.

Please explain about using add with wildcards a bit more.

Regards,
Lovleen.
 
Chandra Bhatt
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I am good with what a reference variable can hold but am still confused with what you can add to it.
I guess, K&B also doesn't go much into add() method except saying that in wildcards can't add anything to it because of the fear that you may add something wrong to it. Though, it does say that when using the keyword super , you may be able to add.

Please explain about using add with wildcards a bit more.



Hi Guptajee,

Ok you got the the point what a reference variable can hold and what can't;
You already have info of, why collection prohibits you to add anything else,
"because you might add anything wrong" : "I like this phrase of K&B"
If I have to tell you in one line about what can be added, if you are allowed yo add Dog, OK! So there is nothing to stop you from anything that is subclass of Dog. This should be crammed to the mind.
In case of wild card, because there is not information regarding what can be added to it, so there can't be added anything to it; but I am sure you wont be confused with adding and assigning an collection object to the reference variable. add() is different and reference assignment is different.

The problem you already know the Cat and Dog, given in detail in the K&B I need not to explain it. What problem there was supposed to occur, you better revise from there if required.

Dont forget, in last three lines we are only concerned with what a reference variable alist can hold. But you should know, you can't add anything to the collection, not even Dog, NOT AT ALL. Compiler does not know what can be subclass of Dog of extends Dog. If you are dead concerned with adding to alist, I can tell you to do it through casting.


Here we are explicitely telling the compiler what we are going to add, so no problemo! Compiler is happy. We did't break the rule here; the rule that we can't add anything to alist; It is still true that we can't add anything to it, but without casting.

Compiler doesn't have any problem when we add the subclass while Dog is required. Because there is no harm.

Yeah Guptajee, now do you feel comfortable? Let me know

Thanks and Regards,
cmbhatt
[ March 31, 2007: Message edited by: Chandra Bhatt ]
 
Lovleen Gupta
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Chandra Bhatt:


Hi Guptajee,


Ok you got the the point what a reference variable can hold and what can't;
You already have info of, why collection prohibits you to add anything else,
"because you might add anything wrong" : "I like this phrase of K&B"
If I have to tell you in one line about what can be added, if you are allowed yo add Dog, OK! So there is nothing to stop you from anything that is subclass of Dog. This should be crammed to the mind.
In case of wild card, because there is not information regarding what can be added to it, so there can't be added anything to it; but I am sure you wont be confused with adding and assigning an collection object to the reference variable. add() is different and reference assignment is different.

The problem you already know the Cat and Dog, given in detail in the K&B I need not to explain it. What problem there was supposed to occur, you better revise from there if required.

Dont forget, in last three lines we are only concerned with what a reference variable alist can hold. But you should know, you can't add anything to the collection, not even Dog, NOT AT ALL. Compiler does not know what can be subclass of Dog of extends Dog. If you are dead concerned with adding to alist, I can tell you to do it through casting.


Here we are explicitely telling the compiler what we are going to add, so no problemo! Compiler is happy. We did't break the rule here; the rule that we can't add anything to alist; It is still true that we can't add anything to it, but without casting.

Compiler doesn't have any problem when we add the subclass while Dog is required. Because there is no harm.

Yeah Guptajee, now do you feel comfortable? Let me know

Thanks and Regards,
cmbhatt

[ March 31, 2007: Message edited by: Chandra Bhatt ]



All right..
Thanks Chandra..! I think I am good to go.
But one questions still remains .. why are we able to add when using wildcard with super..For exmaple (the exp you gave earlier)--

ArrayList<? super String> alist = new ArrayList<String>();

//Now alist reference variable can hold any ArrayList that is parameterized with String or superclass of String, (ofcourse Object class). But the upper bound is String so only and only you are allowed to "add" String object in the list.

alist.add("a");
alist.add(new String("bb");

Cheers..!
 
Chandra Bhatt
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


ArrayList<? super String> alist = new ArrayList<String>();
//Now alist reference variable can hold any ArrayList that is parameterized with String or superclass of String, (ofcourse Object class). But the upper bound is String so only and only you are allowed to "add" String object in the list.

alist.add("a");
alist.add(new String("bb");





Thanks and Regards,
cmbhatt
 
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Collection<?>
because of the sign of ?
we don't know the actually type
thus we can't add anything
But the argument is the type of reference
null is the instance value of reference
So we can use add(null) this method
 
Sam Sunamin
Ranch Hand
Posts: 113
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To cmbhatt :
static void testInteger1(List<? extends Number> alist) { //line 1
alist.add(12); //line 2
for(Number n:alist) { //line 3
System.out.println("Number is "+ n.toString()); //line 4
}

Mehtod testInteger1 has a compile error.

static void testInteger2(List<? super Number> list) { //line 10
list.add(12); //line 11 for(Object n:list) { //line12
System.out.println("Number is "+ n.toString());
}

}

Method testInteger2 compile fine.

Thank you cmbhatt. I finally understand it.
[ April 02, 2007: Message edited by: Sam Sunamin ]
 
reply
    Bookmark Topic Watch Topic
  • New Topic