前情提要: 在力扣 559. N叉树的最大深度 中,官方题解出现了 Collections.max 的用法,本人使用的是 Math.max 这一古老而强大的函数。为什么官方答案选用的是 list 呢?让我们来实际检验效率大小吧!
给定一个数组,求最大值。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Test {
public static void main(String[] args) {
double[] array = new double[10000000];
for (int i = 0; i < 10000000; i++){
array[i] = Math.random();
}
Test t = new Test();
t.collectionsMax(array);
t.mathMax(array);
}
private void collectionsMax(double[] array) {
double ret;
long start = System.currentTimeMillis();
List<Double> list = new ArrayList<>();
for (double num: array) {
list.add(num);
}
ret = Collections.max(list);
long end = System.currentTimeMillis();
System.out.println("Collections.max = " + ret + ", 耗时:" + (end - start));
}
private void mathMax(double[] array) {
double ret = 0;
long start = System.currentTimeMillis();
for (double num: array) {
ret = Math.max(ret, num);
}
long end = System.currentTimeMillis();
System.out.println("Math.max = " + ret + ", 耗时:" + (end - start));
}
}
运行结果如下:
Collections.max = 0.9999999774786892, 耗时:2937
Math.max = 0.9999999774786892, 耗时:17
显然,Collections.max() 函数花费的时间要远大于 Math.max()。那么为什么他还要选用前者呢?从下面源代码来看,两者获取最大值的手法是一样的,都是一个数一个数进行比较。
源代码:
Collections.max() 函数
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
Iterator<? extends T> i = coll.iterator();
T candidate = i.next();
while (i.hasNext()) {
T next = i.next();
// 从这里可以看出,它也是一个一个进行比较的。
if (next.compareTo(candidate) > 0)
candidate = next;
}
return candidate;
}
Math.max() 函数
public static double max(double a, double b) {
if (a != a)
return a; // a is NaN
if ((a == 0.0d) &&
(b == 0.0d) &&
(Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) {
// Raw conversion ok since NaN can't map to -0.0.
return b;
}
return (a >= b) ? a : b;
}