为什么Math.max(double a,double b)不可变? [英] Why isn't Math.max(double a, double b) variadic?

查看:77
本文介绍了为什么Math.max(double a,double b)不可变?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么Math.max的实现不是 variadic函数?

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

它可以像这样实现:

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?

推荐答案

尽管其他人已经回答了为什么 Math.max 不可变的原因,但他们没有回答为什么在以下情况下不创建这样的方法介绍了可变参数功能.

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:

确实没有在 Math 中实现它,但是如果我们查看 Collections ,则可以使用以下方法:

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) {
  ...
}

虽然类型签名看起来很丑陋(它必须足够灵活以处理协方差和协方差),但它可以很容易地与 Collections.max(Arrays.asList(-13,12,1337,9)一起使用); 所有功能实现之后,就在另一个地方.

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.

甚至更好:此方法不仅可以处理double,而且还可以处理实现 Comparable 接口的所有类型.

Even better: This method can handle not only doubles, but all types implementing the Comparable interface.

尽管如此,您建议的解决方案或 Collections 中的解决方案都不是面向对象的,它们只是静态方法.幸运的是,使用 JDK8 ,这种情况将发生变化:

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

对于即将发布的版本,集合库在 Project Lambda 中进行了重新设计,使其更加面向对象.在上面的示例中,Lambda用于提供一种简单易读的方式来确定max元素.以下内容也可以工作:

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

代替 max ,也可以使用高阶函数 reduce :

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

另一个细节是使用 Optional .由于上面示例中所示的高阶函数的组成,它是一种简化错误处理的类型.

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.

lambda提案具有多个优点,因此无需实现可变形式的Math.max:

The lambda proposal has several advantages that make it unnecessary to implement a variadic form of Math.max:

  1. 它是面向对象的
  2. 它是多态的.这意味着它可以与每种类型的集合一起使用( List Set Stream Iterator 等).
  3. 表达力强并且易于理解
  4. 它允许即时并行化.只需将 .stream()更改为 .parallelStream()
  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()

这篇关于为什么Math.max(double a,double b)不可变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆