如何复制数组?高效、优雅

复制数组

1.颜老师,如何复制数组呢?除了for遍历以外,有高效的方法吗?

答:如果数组的元素数量不多,任何一种复制数组的方式都没什么差别。如果数组中包含了大量元素,就确实得考虑效率问题了。有哪些方式呢?

(1)使用你提到的for,以及while等循环遍历赋值(中规中矩,性能一般)

(2)思考,如何才能高效?之所以说for等循环性能一般,是因为java在执行时必然会借助于jvm虚拟机,而jvm是介于操作系统和java代码之间的一个媒介。这个jvm媒介的最大好处就是使得java可以跨语言,但缺点也很明显:多了一道媒介,性能就会减弱一些。因此,要想提高效率,就要想办法绕过这个jvm媒介,怎么绕呢?native,native修改的方法就是操作系统底层自带的方法(java只负责调用,真正由操作系统来执行),因此就得找那些native修饰的方法来提高数组复制的效率。常见有以下三种:

①使用克隆(就是平时说的“深克隆”、“浅克隆”中的那个克隆)

 protected native Object clone() throws CloneNotSupportedException;

但clone()方法的返回值是Object,还需要强制转换成具体的数据类型,而强制转换也会耗费那么一些性能。但整体而言,如果数组元素非常多的话,使用clone()性能已经非常不错了

②使用System.arraycopy()

public static native void arraycopy(Object src,  int  srcPos,Object dest, int destPos,int length);

System.arraycopy()是native修饰的,并且从名字就能知道它可以用于复制数组,完美。

③使用Arrays.copyOf()

    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

Arrays.copyOf()也是native修饰的,但从源码可知它实际又调用了System.arraycopy(),并且也存在着强制类型转换,因此性能稍微比System.arraycopy()低了点。

综上,如果数组中存在着大量元素,System.arraycopy()就是推荐的选择了。

主函数

2.老师,这个main()方法没有static修饰,为什么在编译时也不报错?

public void main(String[] args) {
    System.out.println("hello world");
}

答:有static的main()是程序的入口。没有static修饰的main()就是一个普通的方法而已。编译一个普通的方法为什么要报错?

super

3.super不是调用父类的意思吗?为什么这个题的运行结果是practice01.Demo01

package practice01;...public class Demo01 extends Date {
    private void test(){
        System.out.println(super.getClass().getName());
    }
    public static void main(String[]args){
        new Demo01().test();
    }
}

答:本题有两点需要注意:

(1)本题中,如果把super.getClass().getName()改成getClass().getName(),运行结果是完全一样的,都是practice01.Demo01。明白了吗?

如果子类重写了父类的某个方法/属性,则可以使用super调用父类的方法/属性。但本题中Demo01并没有重写任何Date的方法,因此写不写super是无所谓的。

(2)【本题考点】getClass()是谁定义的?既不是Demo01,也不是Date类。也就是说,本题的extends Date是个障眼法,你把extends Date删除后,运行结果也是一样的,结果仍然会是practice01.Demo01。本题实际就是在考getClass()方法,getClass()是Object类中定义的方法,该类的作用就是:返回运行期间,当前类的名字。显然,本题在运行期间使用的类是Demo01,因此结果就是practice01.Demo01,就这么简单。

- 完 -

推荐阅读

一道三目运算符 | 正确率不足20%

Java小白到大神的心路历程(Java SE)

Java小白到大神的心路历程(Web前端)
答疑 | 面试全对,却没offer?

"hello"+null = ?

读者交流 | JAVA过时了吗?

自己写的java.lang.String能用吗?

答疑 | synchronized有指令重排序的功能吗?

服了,list.add()也会报错!!!

一道JVM面试题,答错率超90%

10行代码2道题,全答对的你月薪多少了?

自己写的java.lang.String能用吗?

猜你喜欢

转载自blog.csdn.net/yanqun007/article/details/105965780