Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't Math.max(double a, double b) variadic?

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?

like image 310
Martin Thoma Avatar asked Feb 23 '13 11:02

Martin Thoma


People also ask

Does math Max work with doubles?

max() function is an inbuilt function in Java which returns maximum of two numbers. The arguments are taken in int, double, float and long.

What is max double in Java?

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.


2 Answers

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.

like image 100
Sergey Kalinichenko Avatar answered Sep 28 '22 07:09

Sergey Kalinichenko


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:

  1. It is object oriented
  2. It is polymorphic. This means it can be used with every type of collection (List, Set, Stream, Iterator etc.)
  3. It is expressive and easy to understand
  4. It allows on-the-fly parallelization. Just change .stream() to .parallelStream()
like image 26
kiritsuku Avatar answered Sep 28 '22 08:09

kiritsuku