StackTc
StackTc
采纳率61.9%
2018-05-26 17:21

数组都clone问题,求解释

10

最近看一本书叫《改善java程序的151个建议》,发现这么一个方法。

 public static int max(int[] data) {
        Arrays.sort(data.clone()); //秒处
        return data[data.length - 1]
 }

这个方法的意图是找到数组中最大的一个数,为什么排序的是克隆对象呢,
因为这个方法的目的是取最大数,通过克隆对象去取的话,不改变原有数组的结构,
可是读者发现这个方法有问题,排序的是克隆对象,取值却还是从原来的数组中取.
请教大家,这个方法应该到底怎么写。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

5条回答

  • dabocaiqq dabocaiqq 3年前

    首先我要解释一点,就是,保持程序的正确性,维持程序的简洁性,是作为程序员的第一要务

    Don’t Cut Yourself: Code Optimization as a Double-Edged Sword。中文翻译:过早优化是万恶之源。
    代码优化的好处多多,但是这并不意味着所有的代码都需要进行优化,有时过度的优化反而适得其反——费时、费力、不讨好。
    “现代计算机科学的鼻祖”Donald Knuth曾说过“过早的优化是万恶之源”,因为:让正确的程序更快,要比让快速的程序正确容易得多。文中讲了7个原则,简单罗列如下:
    1. 究竟要优化什么?
    2. 选择一个正确的优化指标
    3. 优化在刀刃上
    4. 优化层次越高越好
    5. 不要过早优化
    6. 依赖性能分析,而不是直觉
    7. 优化不是万金油

    因此脱离了上下文,不要去讨论代码的效率。
    以你的程序为例,我们首先要搞清楚的是,这个寻找最大数的代码,在整个程序中是否是在热区上。所谓热区,就是说,这个函数是频繁被调用么?或者是程序中耗时最多的代码么?大多数情况下,你写了一个程序(我说的是有一定规模的商业软件),90%的代码,其实都是几乎不被调用的,而只有10%的代码是反复调用,耗时巨大的。在不是热区的代码上“优化”,哪怕程序性能提高了1亿倍,但是程序的运行时间也只能压缩10%。
    然而这么做付出的代价是,程序变得面目全非,到处都是各种奇怪的技巧,难以修改。项目开发进度大大增加。甚至为了性能,引入bug,连正确性都没有办法保证。

    我没有你说的那本书,也没有看到你代码的上下文。
    但是如果这个代码不位于热区,并不需要苛求性能的话,我觉得这么写很清晰,体现了作者明白的意图,就是寻找最大数,并且通过克隆避免对原始数据的顺序的修改嘛。当然,我们有更快的做法,问题是一个会武功的人,需要在吃饭的时候也把筷子当作武器耍弄一番么?

    点赞 6 评论 复制链接分享
  • Andellio Andellio 3年前

    int max = data[0];
    for (int i = 1; i < data.length; ++i)
    if (data[i] > max) max = data[i];

    点赞 3 评论 复制链接分享
  • weixin_38691999 枫叶落林 3年前

    public static int max(int[] data) {
    Arrays.sort(data.clone()); //秒处
    return data[data.length - 1];
    }

    原因:我把data.clone()命名为cloneData
    cloneData相当于复制了一份data数组,而你是对cloneData数组进行排序的,但是返回的却是data数组中的数据。你应该返回cloneData中的数据才是你想要的结果

    点赞 评论 复制链接分享
  • feelcycle_07 默默悟问 3年前
     public class Util {
         public static int max(int[] data) {
             if (0 == data.length) return Integer.MIN_VALUE;
             int[] newData = data.clone();
         Arrays.sort(newData); //秒处
         return newData[newData.length - 1];
         }
    
         public static int getMax(int[] data) {
             if (0 == data.length) return Integer.MIN_VALUE;
             int maxVal = data[0];
             for (int i = 1; i < data.length; i++) {
                 if (data[i] > maxVal) {
                     maxVal = data[i];
                 }
             }
             return maxVal;
         }
    
         public static void main(String[] args) {
             final int NUMBER = 5000;
             final int TEST_NUM = 10000;
             int arr[] = new int[NUMBER];
    
             for (int i = 0; i < NUMBER; i++) {
                 if (i % 2 == 1) arr[i] = i - 1;
                 else arr[i] = i + 1;
             }
    
             long v1 = 0;
             long v2 = 0;
             long startTime = System.currentTimeMillis();
    
             for (int j = 0; j < TEST_NUM; j++) {
                 v1 += max(arr);
             }
    
             long t1 = System.currentTimeMillis();
    
             for (int j = 0; j < TEST_NUM; j++) {
                 v2 += getMax(arr);
             }       
    
             long t2 = System.currentTimeMillis();
    
             System.out.println("v1:" + v1 + ", time:" + (t1 - startTime));
             System.out.println("v2:" + v2 + ", time:" + (t2 - t1));
         }
    }
    

    输出:

    v1:49990000, time:652
    v2:49990000, time:61
    
    

    时间差10倍,所以别随便信书上说的1万以下差别不大。

    点赞 评论 复制链接分享
  • feelcycle_07 默默悟问 3年前
         public static int max(int[] data) {
             int[] newData = data.clone();
         Arrays.sort(newData);
         return newData[newData.length - 1];
         }
    

    这是没效率的方法,不是反面教材?

    点赞 评论 复制链接分享

为你推荐