Why isn't the implementation of Math.max a variadic function?
It could get implemented like this:
public class Main {
public static double max(double... values) {
double max = Double.NEGATIVE_INFINITY;
for (double tmp : values) {
max = max < tmp ? tmp : max;
}
return max;
}
public static void main(String[] args) {
// This works fine:
System.out.println(max(-13, 12, 1337, 9));
// This doesn't work:
// System.out.println(Math.max(-13, 12, 1337));
}
}
Is there any reason why it is not implemented like this?
max() function is an inbuilt function in Java which returns maximum of two numbers. The arguments are taken in int, double, float and long.
The greatest maximum value that a double can have is 1.79769313486231570e+308d. MIN_VALUE public final static double MIN_VALUE. The minimum value a double can have.
The java.lang.Math
has been introduced in JDK 1.0, long before variadic functions were introduced into the language in Java 5.
In addition, efficiency is a concern: if you need two elements most of the time, it is much faster to pass them "inline", without creating an intermediate array to hold them. This also avoids the costs of setting up a loop inside the implementation.
While others already have answered why Math.max
is not variadic, they didn't answer why such a method is not created when variadic functions are introduced.
I even don't know it (there is an open bug-report) so I can only guess:
It is true that it is not implemented in Math
, but if we look into Collections
there is the following method:
public static <T extends Object & Comparable<? super T>> T max(
Collection<? extends T> coll) {
...
}
While the type signature looks ugly (it needs to be flexible enough to handle covariance and contravariance), it can easily be used with Collections.max(Arrays.asList(-13, 12, 1337, 9));
After all the function is implemented, just in a different place.
Even better: This method can handle not only doubles, but all types implementing the Comparable
interface.
Nevertheless neither your suggested solution, nor the solution in Collections
is object oriented, they are just static methods. Luckily with JDK8 this will change:
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
int max(List<Integer> list) {
Optional<Integer> opt = list.stream().max((a,b) -> a-b);
return opt.orElse(Integer.MAX_VALUE);
}
max(Arrays.asList(-13, 12, 1337, 9)); // 1337
max(Arrays.asList()); // 2147483647
For the upcoming release the collection library is reworked in Project Lambda to be more object oriented. In the example above, Lambdas are used to provide an easy and readable way to determine the max element. The following would work too:
import static java.util.Comparators.naturalOrder;
Arrays.asList(-13, 12, 1337, 9)
.stream()
.max(naturalOrder())
.ifPresent(System.out::println); // 1337
Instead of max
one could also use the higher order function reduce
:
Arrays.asList(-13, 12, 1337, 9)
.stream()
.reduce((a,b) -> a > b ? a : b)
.ifPresent(System.out::println); // 1337
Another detail is the use of Optional
. It is a type to simplify error handling due to composition of higher order functions as shown in the examples above.
The lambda proposal has several advantages that make it unnecessary to implement a variadic form of Math.max:
List
, Set
, Stream
, Iterator
etc.).stream()
to .parallelStream()
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