Page 1 of 1
About Question enthuware.ocpjp.v8.2.1792 :
Posted: Thu Sep 01, 2016 3:49 am
by ramy6_1
Hello ,
I tried option number 2 on eclipse and it print 3 as you mentioned , can you please explain a little bit why options 2 and 4 prints the value 3 ?
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Fri Sep 02, 2016 1:36 am
by admin
Please go through the explanation for #2 and let me know which part do you not understand so that I can comment.
-Paul.
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Sun Sep 11, 2016 4:44 am
by ramy6_1
Hello ,
"However, Integer.max works very differently from Integer.compare. The max method returns the maximum of two numbers while the compare method returns a difference between two numbers."
I tried the following to send an explicit Comparator
Comparator<Integer> c2 = (x1, x2) -> x1.compareTo(x2);
System.out.println(ls.stream().max(c2).get()); // print 9
Comparator<Integer> c3 = (x1, x2) -> Integer.max(x1, x2);
System.out.println(ls.stream().max(c3).get()); // print 3
So why difference working but maximum doesn't work ?
You mentioned "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"
That means max - that takes two arguments and return int should work here - since compareTo takes only one arguments
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Sun Sep 11, 2016 11:07 am
by admin
What do you mean by "doesn't work"?? Do you mean doesn't compile or doesn't do what is expected i.e. return the correct value?
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Mon Sep 12, 2016 5:11 am
by ramy6_1
I mean it doesn't get the maximum.
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Mon Sep 12, 2016 10:43 am
by admin
Because Stream's max method is written to work with a Comparator. It expects that the function used for comparison will return the difference between the two numbers. It is coded accordingly. So I am not sure why would you expect it to work with Integer.max method? Integer.max method doesn't return the difference of two numbers.
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Mon Oct 03, 2016 9:31 am
by lucian
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
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Sat Jun 03, 2017 11:16 am
by sedletskiyv
I think the misunderstanding is that the Comparable interface accepts any positive value comparing something with something, so when max() is used even the first element (3) compared with any other (9) is ok, as well as 9 compared to 3.
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Fri Jun 29, 2018 4:23 am
by anojer8
In line 1, the code is:
System.out.println(ls.stream().reduce(Integer.MIN_VALUE, (a, b)->a>b?a:b)); //1
the identity is Integer.MIN_VALUE, if I change it to 0 or -10 or whatever, it just have no effect on the result.
What is the reason for that? Is it because it isn't used in the BinaryOperator?
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Fri Jun 29, 2018 5:23 am
by admin
The Identity value acts as the initial element for the reduction. What if you change your identity value to 10 and have only one element in the stream with value < 10? Or what if there are no elements in the stream? What if your lambda returns a+b instead of a>b?a:b ?
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Fri Jul 13, 2018 12:42 pm
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.
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Thu Jul 26, 2018 5:35 pm
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; }
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Mon Aug 12, 2019 12:56 pm
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)
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Sun Sep 01, 2019 9:35 am
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
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Tue Dec 03, 2019 8:54 am
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.
Re: About Question enthuware.ocpjp.v8.2.1792 :
Posted: Tue Dec 03, 2019 8:51 pm
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.