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

前端 未结 6 958
逝去的感伤
逝去的感伤 2021-01-12 23:33

Why isn\'t the implementation of Math.max a variadic function?

It could get implemented like this:

public class Main {
    public static double max(d         


        
6条回答
  •  Happy的楠姐
    2021-01-12 23:57

    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 max(
        Collection 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 list) {
      Optional 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()

提交回复
热议问题