虽然其他人已经回答了为什么Math.max
不是可变参数,但他们没有回答为什么在引入可变参数函数时没有创建这种方法。
我什至不知道(有一个打开的错误报告)所以我只能猜测:
确实它没有在 中实现Math
,但是如果我们研究一下Collections
,有以下方法:
public static <T extends Object & Comparable<? super T>> T max(
Collection<? extends T> coll) {
...
}
虽然类型签名看起来很丑(它需要足够灵活来处理协变和逆变),但它可以很容易地用于Collections.max(Arrays.asList(-13, 12, 1337, 9));
在所有函数实现之后,只是在不同的地方。
更好的是:此方法不仅可以处理双精度数,还可以处理实现Comparable
接口的所有类型。
尽管如此,您建议的解决方案和解决方案都不Collections
是面向对象的,它们只是静态方法。幸运的是,使用JDK8这将改变:
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 用于提供一种简单易读的方法来确定最大元素。以下内容也可以:
import static java.util.Comparators.naturalOrder;
Arrays.asList(-13, 12, 1337, 9)
.stream()
.max(naturalOrder())
.ifPresent(System.out::println); // 1337
代替max
一个也可以使用高阶函数reduce
:
Arrays.asList(-13, 12, 1337, 9)
.stream()
.reduce((a,b) -> a > b ? a : b)
.ifPresent(System.out::println); // 1337
另一个细节是使用Optional
. 由于如上例所示的高阶函数的组合,它是一种简化错误处理的类型。
lambda 提案有几个优点,不需要实现 Math.max 的可变参数形式:
- 它是面向对象的
- 它是多态的。这意味着它可以用于每种类型的集合(
List
、Set
、Stream
等Iterator
)
- 它富有表现力且易于理解
- 它允许即时并行化。只需更改
.stream()
为.parallelStream()