About Question enthuware.ocpjp.v8.2.1792 :

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

Moderator: admin

Post Reply
__JJ__
Posts: 125
Joined: Thu Jul 05, 2018 6:44 pm
Contact:

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

Post by __JJ__ »

For anyone who's just come to this, I think the easiest way to explain it is this:
1. they all compile because the function signatures match the requirement of Stream.max which is for a method signature that matches Comparator's int compare(T o1, T o2) method
2. 2 and 4 don't work because they always return a positive number, which the Stream.max function interprets as meaning: the first argument is larger than the second (remember every implementation of compare is supposed to return a +ve number if the first operand is larger than the second), so what happens is it keeps the first and moves on to the comparison of the next element.

That's my understanding; apologies if it's incorrect.

__JJ__
Posts: 125
Joined: Thu Jul 05, 2018 6:44 pm
Contact:

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

Post by __JJ__ »

The Stream.max method requires a Comparator. All you need to implement this interface using a lambda expression is a reference to any method that takes two arguments and returns an int.
I know what you mean but it's still important that the types for the arguments are the same and non-primitive and that if the Comparator is untype the only valid type is Object:

Code: Select all

          Comparator c1 = (a,b) -> 1;                           //OK
          Comparator c2 = (int a, int b) -> 1;                  //DOESN'T COMPILE
          Comparator c3 = (Object a, Integer b) -> 1;           //DOESN'T COMPILE
          Comparator c4 = (Integer a, Integer b) -> 1;          //DOESN'T COMPILE   
          Comparator<Integer> c4 = (Integer a, Integer b) -> 1; //OK
Of course these are not the same as method references; they are just easier for me to type than multiple methods but still:

Code: Select all

    Comparator c5 = T23::fooA;              //DOESN'T COMPILE
    Comparator c6 = T23::fooB;              //DOESN'T COMPILE
    Comparator<Double> c7 = T23::fooB;      //OK
    static int fooA(int a, int b) { return 0; }
    static int fooB(Double d, Double d2) { return 0; }

sir_Anduin@yahoo.de
Posts: 62
Joined: Fri Aug 07, 2015 2:16 pm
Contact:

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

Post by sir_Anduin@yahoo.de »

I think the max method needs some kind of sorter. And when sorted, it takes the first (or last) element in the list. Of cource sorting with Integer::max does not work, as it does not fulfill the Comparator.compare contract:
which is defined to return one of -1, 0, or 1 according to whether the value of expression is negative, zero or positive.
from
https://docs.oracle.com/javase/8/docs/a ... re(T,%20T)

tylrdr
Posts: 6
Joined: Sun Sep 01, 2019 9:33 am
Contact:

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

Post by tylrdr »

lucian wrote:
Mon Oct 03, 2016 9:31 am
Maybe this will make understanding easier the difference between Integer.max() and Integer.compare() methods usage in a stream max method

Code: Select all

        System.out.println("USING Integer.max()");
        System.out.println(ls.stream().max((o1, o2) -> {System.out.print(o1);
                                                        System.out.print(o2);
                                                        int max = Integer.max(o1, o2);
                                                        System.out.print(max);
                                                        System.out.print("\t");
                                                        return max;})
                                      .get());
        System.out.println("USING Integer.compare()");
        System.out.println(ls.stream().max((o1, o2) -> {System.out.print(o1);
                                                        System.out.print(o2);
                                                        int max = Integer.compare(o1, o2);
                                                        System.out.print(max);
                                                        System.out.print("\t");
                                                        return max;})
                                      .get());

Code: Select all

USING Integer.max()
344	366	399	323	355	377	3
USING Integer.compare()
34-1	46-1	69-1	921	951	971	9
I added some comments to your excellent code for my own understanding. Thank you sir! Maybe someone finds my comments useful when understanding this question)

https://paste.ee/p/EiT6L

Bhaskar
Posts: 19
Joined: Fri Aug 02, 2019 7:04 am
Contact:

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

Post by Bhaskar »

I would like to add my explanation/understanding to all the excellent answers above.
The confusion for me came specifically from the fact that Integer.max() always returns the largest value as opposed to Integer.compare() method, that returns the difference between the comparing values.

For example:

Code: Select all

List<Integer> ls = Arrays.asList(-1, 4, 6);
System.out.println(ls.stream().max((x, y) -> {
            System.out.println(x + " " + y);
            System.out.println("max: " + Integer.max(x, y));
            System.out.println("");
            return Integer.max(x, y);
        }).get());
o/p:
-1 4
max: 4

-1 6
max: 6

-1

Although at each iteration in Comparator the maximum value is clearly defined, the stream().max() method sees the values in terms of +ve, -ve or 0.
Therefore, max(-1, 4) returns a positive value (i.e. 4) and stream().max() method thinks that -1 is greater than 4 and uses it for further comparisons. For more clarity, look at the following example:

Code: Select all

List<Integer> ls = Arrays.asList(-1, 4, -2, 6);
        System.out.println(ls.stream().max((x, y) -> {
            System.out.println(x + " " + y);
            System.out.println("max: " + Integer.max(x, y));
            System.out.println("");
            return Integer.max(x, y);
        }).get());
o/p:
-1 4
max: 4

-1 -2
max: -1

-2 6
max: 6

-2

In contrast, Integer.compare() checks the adjacent values and works similarly as calling Comparable interface's compareTo method.

Please feel free to correct me if I'm wrong.

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

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

Post by admin »

Stream's max(Comparator c) expects a Comparator. A Comparator's contract is given in its API JavaDoc:
Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
So, yes, if you use Integer.max to build a Comparator for Stream's max, it will give weird results as your example shows.
If you like our products and services, please help us by posting your review here.

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 34 guests