aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Collections and Generics Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Collections and Generics" Watch "Collections and Generics" New topic
Author

Collections and Generics

Andi Dan
Greenhorn

Joined: Feb 28, 2011
Posts: 18
The question is from "ETS Question" and I don't know why they answer in this way.
The code is:

Choose form following options(only once) to insert at line #1 and #2:

b = dataList.get(0);
t = dataList.get(0);
dataList.add(t)
dataList.add(b)

Here is my answer and I'll explain why I've chosen this:
// insert 1 - dataList.add(b)
Because we have (addData1 List <? super Dooby> dataList) it means that the list accepts as parameters only (super types of Dooby) or Dooby types. This means that it accepts a Boody (is a super type of Dooby because Dooby extends Boody) type or even a type of Dooby (but is not in the options). Based on this logic i've chosen dataList.add(b).

ETS answer: dataList.add(t)
and they they explain like this:
"This means that dataList is a List whose elements are of a class that is either Dooby or a super class of Dooby. We don't know which super class of Dooby. Thus, if you try to add any object to dataList, it has to be a assignable to Dooby. "
- what do you mean assignable to Dooby... ??? it can be anything that's a super to Dooby or a Dooby, because Dooby IS A (super) no matter what.
"Thus, dataList.add(b); will be invalid because b is not assignable to Dooby. "
--- b is a super for Dooby. I don't see why it cannot be added.

// insert 2 - t = dataList.get(0);
Because we have addData2 (List <? extends Dooby> dataList) it means that the list accepts as parameters only (subtypes of Dooby) or Dooby types. This means that it accepts a Toody (is a subtype of Dooby because Tooby extends Doody) type or even a type of Dooby (but is not in the options). Since the operator <? extends> doesn't allow us to add anything to the list(it will result in a compiler error) then I've chosen t = dataList.get(0);

For example we can pass addData2(List<Toby>) since <Toby> is s subtype of <Dooby> and when I acces get() I should find a <Toby> object.

ETS responded
b = dataList.get(0);

"This means that dataList is a List whose elements are of a class that is either Dooby or a subclass of Dooby. Since we don't know which subclass of Dooby is the list composed of, there is no way you can add any object to this list."
- the part with "don't know witch subclass of Dooby is the list composed of" - Tooby is a subclass of Dooby in this example.

"If you try to take some object out of dataList, that object will be of a class that is either Dooby or a subclass of Dooby and thus it can be assigned to a variable of class Dooby or its superclass.. Thus, t = dataList.get(0) ; is invalid." - don't get it!!!


So to review at the end I've chosen:

// insert 1 - dataList.add(b)
// insert 2 - t = dataList.get(0);
and ETS:
// insert 1 - dataList.add(t)
// insert 1 - b = dataList.get(0);



For me is important to know if this a mistake from ETS or I'm compleately reading this wrong. If wrong.. how it should be be?
dennis deems
Ranch Hand

Joined: Mar 12, 2011
Posts: 808
You seem to have an inverted notion of inheritance. It is the subclass instance that IS-A superclass. NOT the other way around.

Andi Dan wrote:Because we have (addData1 List <? super Dooby> dataList) it means that the list accepts as parameters only (super types of Dooby) or Dooby types. This means that it accepts a Boody (is a super type of Dooby because Dooby extends Boody) type or even a type of Dooby (but is not in the options). Based on this logic i've chosen dataList.add(b).

It seems, when we first encounter generics, that's what it should mean. But it doesn't. It means that the method accepts as a parameter a List of an unknown type, which must be Dooby or a supertype of Dooby. You will avoid many missteps, when you encounter a generic wildcard, if you always formulate it in this way.

Suppose we have a List<Boody>. Could we add a Boody instance? Sure. Could we add a Tooby instance? Sure. BUT: suppose we have a List<Dooby>. Now we can still add the Tooby instance, but NOT the Boody instance.

what do you mean assignable to Dooby... ??? it can be anything that's a super to Dooby or a Dooby, because Dooby IS A (super) no matter what.
"Thus, dataList.add(b); will be invalid because b is not assignable to Dooby. "
--- b is a super for Dooby. I don't see why it cannot be added.


The IS-A relationship only works in one direction. This is a concept you must learn so it is second nature. We can say that every Apple IS-A Fruit, but not every Fruit IS-A Apple. In the same way, we can say that every Dooby is a Boody, but we can't say that every Boody is a Dooby.

Would we be able to do this?:
No. We can not add Fruit to a list of Apples.

"If you try to take some object out of dataList, that object will be of a class that is either Dooby or a subclass of Dooby and thus it can be assigned to a variable of class Dooby or its superclass.. Thus, t = dataList.get(0) ; is invalid." - don't get it!!!


If we have a basket of fruit, and we take something from it, can we be sure we will get an apple? What if the basket contains nothing but Oranges?


Andi Dan
Greenhorn

Joined: Feb 28, 2011
Posts: 18
In your example when cast is done it will throw a RuntimeException because it tries to cast the Orange to the Apple.


My mistake was that I interpreted wrong.
append1 (List<? super Dooby> dataList ) - means that the method accepts as an argument "a LIST" that can contain elements be a type of Dooby or any superclass of it.

not as... the list can add elements of supertypes of Dooby. The parameter List<? super Dooby> can be in the shape List<Dooby> or List<Boody>

Tks a lot!
Satya Maheshwari
Ranch Hand

Joined: Jan 01, 2007
Posts: 368
If I may, this is the way I look at generics. Whenever there is a generic type specified, ask yourself, if that collection were a closed bag, what could you conclusively say about the contents of that bag.

Let's consider a class hierarchy as follows for simplicity:

Let's say we have bag called Collection<Apple>. I can conclusively say that this bag contains
1.Apples
2.Fruits (because apple IS A fruit)
3.Eatable

Let's say we have bag called Collection<? extends Apple>. I can conclusively say that this bag contains
1.Apples
2.Fruits (because any type of apple IS A fruit)
3.Eatable

I cannot say that this bag contains Red Apples as this bag may also contain green apples

Let's say we have bag called Collection<? super Apple>. I can conclusively say that this bag contains
1.Something (equivalent to Object in java)

I cannot say anything else conclusively about this bag.

Thanks and Regards
Paul Anilprem
Enthuware Software Support
Ranch Hand

Joined: Sep 23, 2000
Posts: 3313
    
    7
Hi Andi, You might want to check out this short article on generics.

Satya, you have got the right idea about taking things out of the bag. The second part of it is what can you put in the bag.

HTH,
Paul.


Enthuware - Best Mock Exams and Questions for Oracle/Sun Java Certifications
Quality Guaranteed - Pass or Full Refund!
Andi Dan
Greenhorn

Joined: Feb 28, 2011
Posts: 18
Having the following class structure:



1.List<? extends Apple>

Suppose we have a method called ExtendsMeth(List<? extends Apple> thing)
ExtendsMeth accepts any list of shape type that extends Apple:

a. List(Apple)
b. List(RedApple)
c. List(YellowApple)

ExtendsMeth (List<? extends Apple> thing)
// can't work :
thing.add(new RedApp) - because list can have one of the shapes and a. b. c. and you can't have for example a RedApple list and add a YellowApple to that list and for this the compliler takes care and if you try method add then you'll get a compiler error.

//work:
you can try instead to get something from the list
thing.get(0); // when you get() the thing can be anything from Apple,RedApple,YellowApple so you can't be sure what you'll get.
you can try to reference the thing with a reference variable whitch has to be of superior type of what you would posible get from the thing(you can get from the thing Apple,RedApple,YellowApple) whitch means the reference variable can be o type Apple or a super type of Apple.
You can't have for example a list of Apples and a reference type as RedApple.You can't say thing(thing is a Apple now):
RedApple red;
red = thing.get(0);

But you can say:
Etable eat;
eat = thing.get(0);
or
Object = thing.get(0);


2.List<? super Apple>

Suppose we have a method called SuperMeth(List<? super Apple> thing)
SuperMeth accepts any list of shape that Apple IS-A (super of Apple):
a.List<Apple>
b.List<Fruit>
c.List<Etable>


When adding to thing you should take care of what the shape can be.
You can't say thing.add(new Etable) because thing can be anything of a. b. c. So if list is of type List<Apple> you can't add new Etable to a list of Apple.
You can add for example Apple or a Apple subtype because any shape list can manage the Apple because Apple IS - A Fruit or Etable.

When you want to get() from the list then you can use a reference variable that is of type Etable or Object. It must reference the same type of object or a subtype.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Collections and Generics