Stream.max (Integer :: max): Unexpected result

I am learning 1z0-809: Java SE 8 Programmer II using Enthuware layouts.

Meet this question.

List<Integer> ls = Arrays.asList(3,4,6,9,2,5,7); System.out.println(ls.stream().reduce(Integer.MIN_VALUE, (a, b)->a>b?a:b)); //1 System.out.println(ls.stream().max(Integer::max).get()); //2 System.out.println(ls.stream().max(Integer::compare).get()); //3 System.out.println(ls.stream().max((a, b)->a>b?a:b)); //4 

Which of the above statements prints 9?

Answer

1 and 3

But there is something else. I do not understand why

 System.out.println(ls.stream().max(Integer::max).get()); // PRINTS 3 

I tried debugging it using peek , but that doesn't help me understand.

I tried sorting ls using Integer::max and Integer::compare

 ls.sort(Integer::max); // [3, 4, 6, 9, 2, 5, 7] ls.sort(Integer::compare); // [2, 3, 4, 5, 6, 7, 9] 

Of course, I get the fact that Integer::max not a comparator, so it has the same signature. For me, max should be 7 in the first case, since this is the last element, for example, when I sorted using Ìnteger::compare

Can someone break this into something simple?

+5
source share
3 answers

Integer.max(a, b) will return a larger value for data a and b . If you somehow use this result as a comparator, the returned positive value will be considered the value a > b , so a will be saved.

The first two elements are 3 and 4. Both are positive. Integer.max(3, 4) = 4 > 0 . Thus, you effectively say that 3 > 4 with such a comparator, so 3 is saved. Then the same applies to the rest: Integer.max(3, 6) = 6 > 0 , so 3 is considered max, etc.

+8
source

The contract of the comparator method (according to the arguments first , second ):

  • return 0 if first is second
  • return a negative value if first < second
  • returns a positive value if first > second

The max method with positive values ​​always returns a positive value. When interpreting the return value in accordance with the comparator contract, a positive value means first > second . As a result, the ordering of the elements does not change; they look "ordered."

+6
source

This is incredibly confusing.

We are trying to use Integer::max as a comparator. Since all numbers in the question are positive, the answer is always interpreted as meaning that the first argument to compare(a, b) is “larger” than the second.

One of the features of Collections.sort is that when you have a list [a, b] , the method is programmed so that it is called compare(b, a) , not compare(a, b) (which would seem more reasonable), Therefore, if compare returns a positive number, it looks like b > a , so the list does not need to be sorted.

This is why list.sort does nothing.

However, it just happens that Stream.max programmed the other way around, i.e. The first comparison is compare(3, 4) , so it looks like 3 is the maximum.

+6
source

Source: https://habr.com/ru/post/1245437/


All Articles