About Question enthuware.ocpjp.v8.2.1830 :

Help and support on OCA OCP Java Programmer Certification Questions
1Z0-808, 1Z0-809, 1Z0-815, 1Z0-816, 1Z0-817

Moderator: admin

Post Reply
schchen2000
Posts: 106
Joined: Mon Mar 28, 2016 11:36 pm
Contact:

About Question enthuware.ocpjp.v8.2.1830 :

Post by schchen2000 »

It is important to understand that compilation failure occurs because books is declared as List<Book>. If it were declared as just List, compilation would succeed and it would fail at run time with a ClassCastException.
This is from the explanation under the 2nd answer option.

What I understood from the above quote was that the code will compile but will throw a ClassCastException if we have

Code: Select all

List books = getBooksByAuthor("Ludlum");

Collections.sort(books); //2 
instead.

Basically,

List books = getBooksByAuthor("Ludlum");

is the same as

List<?> books = getBooksByAuthor("Ludlum");

or

List<? extends Object> books = getBooksByAuthor("Ludlum");

Before we can do any sorting, we definitively need to know the type of an object we want to sort but having

List<?> books = getBooksByAuthor("Ludlum");

or

List<? extends Object> books = getBooksByAuthor("Ludlum");

will NOT give us the definitive type of an object we want to sort and thus compiler throws an exception.

In short, the exception occurs even before sorting begins.

Is that correct?

Hypothetically speaking, even if ClassCastException were no issue, the code would still end up not working because to sort an object, the class that the object belongs to would have to implement Comparable Interface or would have to use Comparator Interface somehow to do the sorting.

Am I understanding this correctly?

Thanks.

Schmichael

pushpa
Posts: 7
Joined: Thu Apr 28, 2016 4:59 am
Contact:

Re: About Question enthuware.ocpjp.v8.2.1830 :

Post by pushpa »

This is a valid usage of a lambda expression to implement a Comparator.
This is the explanation given for first option. Should not it be Comparable interface instead of Comparator?

schchen2000
Posts: 106
Joined: Mon Mar 28, 2016 11:36 pm
Contact:

Re: About Question enthuware.ocpjp.v8.2.1830 :

Post by schchen2000 »

pushpa wrote:
This is a valid usage of a lambda expression to implement a Comparator.
This is the explanation given for first option. Should not it be Comparable interface instead of Comparator?
NO! The explanation was correct.

First of all, to use a Comparable Interface, the class has to implement it. In the question, the class did not implement Comparable Interface. If what you said were true, i.e. "Should not it be Comparable interface instead of Comparator?"

The line in the code indicated by //1 would have failed but it did not!

Here is another proof:

Using a Comparator Interface does not require a class to implement it. That's a major difference between Comparable and Comparator interfaces.

Comparator Interface can be used in a class in an "in-line" or "on-the-fly" fashion for lack of a better word.

Here is another difference between Comparable and Comparator Interfaces.

Comparable Interface has compareTo() functional method which has only ONE parameter where as

Comparator Interface has Compare() functional method which has TWO parameters.

So, if you look at the line of code with //1, you will see TWO parameters used in the Lambda Expression. So, it's definitely Comparator Interface, not Comparable Interface as you suggested.

Hope that helps!

Schmichael

admin
Site Admin
Posts: 10388
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocpjp.v8.2.1830 :

Post by admin »

schchen2000 wrote:
It is important to understand that compilation failure occurs because books is declared as List<Book>. If it were declared as just List, compilation would succeed and it would fail at run time with a ClassCastException.
This is from the explanation under the 2nd answer option.

What I understood from the above quote was that the code will compile but will throw a ClassCastException if we have

Code: Select all

List books = getBooksByAuthor("Ludlum");

Collections.sort(books); //2 
instead.
Correct.
Basically,

List books = getBooksByAuthor("Ludlum");

is the same as

List<?> books = getBooksByAuthor("Ludlum");

or

List<? extends Object> books = getBooksByAuthor("Ludlum");
No, a non-generified List variable is not same as List<?> or List<? extends Object>. List is totally unbound. Compiler will let you add anything to it and take anything out of it. It will not worry about potential ClassCastExceptions at run time. List<?> means a specific type which, currently, i.e. at compile time, is unknown. Since that type is not known at compile time, you're cannot modify the list. i.e. you cannot add anything to it and you can only take out Objects.
Before we can do any sorting, we definitively need to know the type of an object we want to sort but having

List<?> books = getBooksByAuthor("Ludlum");

or

List<? extends Object> books = getBooksByAuthor("Ludlum");

will NOT give us the definitive type of an object we want to sort and thus compiler throws an exception.
No, we don't need to know the exact type of the object. We just need to make sure that the class of the objects implements Comparable.

BTW, I know what you mean but "compiler throws an exception" is not a correct way to say it. Compiler doesn't throw exceptions because it doesn't execute any code. Compiler "raises an error" or "fails to compile" or "generates an error message" are better.
In short, the exception occurs even before sorting begins.

Is that correct?
I am not sure what do you mean by "before" sorting begins. It exactly the time when you start sorting, you want to cast the object to Comparable. Since the object (i.e. its class) is not Comparable, a ClassCastException will be thrown by the JVM.
Hypothetically speaking, even if ClassCastException were no issue, the code would still end up not working because to sort an object, the class that the object belongs to would have to implement Comparable Interface or would have to use Comparator Interface somehow to do the sorting.

Am I understanding this correctly?
Probably. ClassCastException happens because the class doesn't implement Comparable. So in that sense, yes, ClassCastException is the not the cause but a symptom.

HTH,
Paul.

schchen2000
Posts: 106
Joined: Mon Mar 28, 2016 11:36 pm
Contact:

Re: About Question enthuware.ocpjp.v8.2.1830 :

Post by schchen2000 »

List is totally unbound.
How can you have the unbounded list when Object is the mother of all classes in Java. So, wouldn't Object class be the "ultimate" bound?
Of course, every object is an Object. That limitation goes without saying. It has nothing to do with List though. That restriction is not imposed by List but by Java language because every object is an Object. Also, I used the word unbound here in the sense that there is no restriction on what you can add or retrieve from it that is enforced by the compiler.
List<?> means a specific type which, currently, i.e. at compile time, is unknown.
I think it's a bit misleading statement.

Counter example:

List<String> str = Arrays.asList("Hello", "World!");

List<?> foo = str; // The compiler knows that it's dealing with String here, doesn't it?
No, that is a wrong analogy. We are talking about the type of foo as it is declared. Try taking a String out of foo. Something like String s = foo.get(1);
Since that type is not known at compile time, you're cannot modify the list.
I think this one is also a bit misleading as well.

Counter example:

List<Integer> str = Arrays.asList(1, 2, 3);

List<? super Number> foo = str; // After this statement, we can modify foo using an object made instantiated from Number or its subclasses.
We are talking about List<?> not List<? super Number>. You cannot add anything to foo if foo is declared as List<?>.

You may want to go through this site to learn about generics in details and then come back to this. It is very good - http://www.angelikalanger.com/GenericsF ... csFAQ.html

pushpa
Posts: 7
Joined: Thu Apr 28, 2016 4:59 am
Contact:

Re: About Question enthuware.ocpjp.v8.2.1830 :

Post by pushpa »

public int compareTo(Book b){         return this.isbn.compareTo(b.isbn);     }
Collections.sort(books, (b1, b2)->b1.getTitle().compareTo(b2.getTitle())); //1
Above are the lines of code
Comparable Interface has compareTo() functional method which has only ONE parameter where as

Comparator Interface has Compare() functional method which has TWO parameters.

So, if you look at the line of code with //1, you will see TWO parameters used in the Lambda Expression. So, it's definitely Comparator Interface, not Comparable Interface as you suggested.
Points to disagree,

1.Comparable interface has no compareTo method.
2.The method here in the lamda takes only one parameter.
Using a Comparator Interface does not require a class to implement it. That's a major difference between Comparable and Comparator interfaces.
I dont agree with that, as comparable is implemented by almost all class. On the other had comparator which is used in sort has to be implemented.
Again the compareTo method had getTitle which was String, string class implements comparable so I thought it need not implement comparable.
Collections.sort(books, (b1, b2)->b1.getTitle().compareTo(b2.getTitle())); //1
Another thing confusing was Collections.sort when it takes second argument it will be comparator, then it should be compare(a,b) method and in this case you are correct. But here it was compareTo which confused me.

pushpa
Posts: 7
Joined: Thu Apr 28, 2016 4:59 am
Contact:

Re: About Question enthuware.ocpjp.v8.2.1830 :

Post by pushpa »

Points to disagree,

1.Comparable interface has no compareTo method.
Sorry its not Comparable "Comparator". Comparable has indeed compareTo method.

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests