About Question enthuware.ocpjp.v8.2.1889 :

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

Moderator: admin

Post Reply
javasaur
Posts: 3
Joined: Sat Feb 03, 2018 10:04 am
Contact:

About Question enthuware.ocpjp.v8.2.1889 :

Post by javasaur »

Hi there,

as I skimmed the question I marked this line as a potential compile-error and marked option E,

Code: Select all

ToDoubleFunction<Item> priceF = Item::getPrice; //1
since I assumed that the default class construction implies non-static getters and setters and no static method is provided to the interface. But the question seems to have an assumed part like this:

Code: Select all

public static double getPrice(Item i) {
    return i.getPrice();
}

public double getPrice() { 
    return price;
}
Did I get it right? If yes, is it something I should expect on the exam or did you assume it by yourself?

Thanks

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

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

Post by admin »

It code does assume the existing of accessor methods i.e. getXXX and setXXX for each of the three properties of Item class. It contains this line in the code: //accessors not shown
This implies that the accessor methods are there but are not shown here in the code listing.

But the static getter that you've mentioned is not a valid getter method for the price field and is not required to answer the question either.

HTH,
Paul.

javasaur
Posts: 3
Joined: Sat Feb 03, 2018 10:04 am
Contact:

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

Post by javasaur »

I copied the code, added the getters and the code compiled.
I've built the function with full syntax and tried to reduce part by part

Code: Select all

ToDoubleFunction<Item> priceF = (Item i) -> {return i.getPrice();};
became

Code: Select all

ToDoubleFunction<Item> priceF = Item -> Item.getPrice();
which eventually became

Code: Select all

ToDoubleFunction<Item> priceF = Item::getPrice;
All options compile and result in the same output, but I am still confused. How Java does allow to invoke an instance method on Item? It's a class name. I thought it would check for a static method getPrice() and result in compiler error since it's not found.
Could you clarify this aspect?

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

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

Post by admin »

Your understanding about Item::getPrice; is incorrect. Item::getPrice is not an actual call to any method. It is just a reference to the getPrice method of Item class. That this method is static or not has nothing to do with what Item::getPrice means. That is why no instance is required to refer to the getPrice method. Again, you are not calling the getPrice method at this point. You are merely saying that you are going to use the getPrice method of Item class later.

Now, when you say, ToDoubleFunction<Item> priceF = Item::getPrice; you are saying that you will use Item class's getPrice method to implement the ToDoubleFunction<Item> interface. Again, you are not calling the getPrice method yet. Only declaring that the applyAsDouble function (which is what ToDoubleFunction requires you to implement) will use Item class's getPrice method in its body.


Finally, the place when the method is actually invoked is when collect(Collectors.averagingDouble(priceF)). Here, you actually need an object of class Item on which getPrice method can be invoked. This Item object is supplied by the stream which you are iterating over in that call. So when the compiler generates the byte code for this collect call, it knows how to implement the ToDoubleFunction's applyAsDouble method. At this time, it will make use of the fact that getPrice method of Item class is an instance method and it will check whether there is an Item instance available in the context at that time. Indeed, while looping through a collection of Items, every iteration does have a reference to an Item object. Thus, the compiler will generate the body of this function with code that invokes the getPrice method on the reference to the Item object that the loop is currently iterating over.

HTH,
Paul.

javasaur
Posts: 3
Joined: Sat Feb 03, 2018 10:04 am
Contact:

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

Post by javasaur »

Thanks, Paul.
You made it clear.

yassine
Posts: 8
Joined: Thu Dec 07, 2017 4:43 am
Contact:

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

Post by yassine »

From the java doc I read that forEach takes a Consumer not a BiConsumer:

Code: Select all

forEach([b]Consumer[/b]<? super T> action)
Performs an action for each element of this stream.
so how is that :
.forEach((a, b)->{
double av = b.stream().collect(Collectors.averagingDouble(priceF)); //3
System.out.println(a+" : "+av);
});

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

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

Post by admin »

Actually, collect(Collectors.groupingBy(Item::getCategory)) returns a Map and Map's forEach takes a BiConsumer.

Post Reply

Who is online

Users browsing this forum: No registered users and 5 guests