This is my code
List<Integer> ints = Stream.of(1,2,4,3,5).collect(Collectors.toList());
Integer maxInt = ints.stream()
.max(Comparator.comparing(i -> i))
.get();
System.out.println("Maximum number in the set is " + maxInt);
output:
Maximum number in the set is 5
I cannot make distingues between two i
in below section of my code
Comparator.comparing(i -> i)
can anyone be kind and explain the difference between two i
?
The max() method is an inbuilt method of Math class which is present in java. lang package that is used to find the maximum of two numbers. The max() method takes two inputs that are of types numbers, i.e., int, float, double, and returns the maximum of the given numbers.
Calling stream() method on the list to get a stream of values from the list. Calling mapToInt(value -> value) on the stream to get an Integer Stream. Calling max() method on the stream to get the max value. Calling orElseThrow() to throw an exception if no value is received from max()
2. Using Stream. max() method. The idea is to convert the list into a Stream and call Stream#max() that accepts a Comparator to compare items in the stream against each other to find the maximum element, and returns an Optional containing the maximum element in the stream according to the provided Comparator .
With the introduction of Stream with Java 8, we can convert the array into the corresponding type stream using the Arrays. stream() method. Then we can call the max() and min() method, which returns the maximum and minimum element of this stream as OptionalInt .
The method Comparator.comparing(…)
is intended to create a Comparator
which uses an order based on a property of the objects to compare. When using the lambda expression i -> i
, which is a short writing for (int i) -> { return i; }
here, as a property provider function, the resulting Comparator
will compare the values itself. This works when the objects to compare have a natural order as Integer
has.
So
Stream.of(1,2,4,3,5).max(Comparator.comparing(i -> i))
.ifPresent(maxInt->System.out.println("Maximum number in the set is " + maxInt));
does the same as
Stream.of(1,2,4,3,5).max(Comparator.naturalOrder())
.ifPresent(maxInt->System.out.println("Maximum number in the set is " + maxInt));
though the latter is more efficient as it is implemented as singleton for all types which have a natural order (and implement Comparable
).
The reason why max
requires a Comparator
at all, is because you are using the generic class Stream
which might contain arbitrary objects.
This allows, e.g. to use it like streamOfPoints.max(Comparator.comparing(p->p.x))
to find the point with the largest x
value while Point
itself does not have a natural order. Or do something like streamOfPersons.sorted(Comparator.comparing(Person::getAge))
.
When using the specialized IntStream
you can use the natural order directly which is likely to be more efficient:
IntStream.of(1,2,4,3,5).max()
.ifPresent(maxInt->System.out.println("Maximum number in the set is " + maxInt));
To illustrate the difference between “natural order” and a property based order:
Stream.of("a","bb","aaa","z","b").max(Comparator.naturalOrder())
.ifPresent(max->System.out.println("Maximum string in the set is " + max));
this will print
Maximum string in the set is z
as the natural order of String
s is the lexicographical order where z
is greater than b
which is greater than a
On the other hand
Stream.of("a","bb","aaa","z","b").max(Comparator.comparing(s->s.length()))
.ifPresent(max->System.out.println("Maximum string in the set is " + max));
will print
Maximum string in the set is aaa
as aaa
has the maximum length of all String
s in the stream. This is the intended use case for Comparator.comparing
which can be made even more readable when using method references, i.e. Comparator.comparing(String::length)
which almost speaks for itself…
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With