java基础复习七:数组的声明与扩容

如何声明数组,有几种方式,面试的时候经常被问道,每次都是临时记一下,也没有认真对待这个问题,现在复习一下。

数组的声明

最常用的声明方式

代码:

public static void main(String[] args) {

        String[] strArr = new String[10];
        strArr[10] = "145";
    }

这是我最常用的声明方式,大多数使用数组时,都能确定数组中元素的个数。
这种写法,只是初始化了容量,但是具体的元素需要另外赋值。

但是一旦超过指定的容量,就会报错,上面代码执行就会报下面这个错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
    at test.TestArray.main(TestArray.java:14)
第二种声明方式

代码:

public static void main(String[] args) {

        String[] strArr = new String[]{"0", "1"};

        strArr[10] = "145";
    }

这种写法不明显制定数组的容量,但是直接写出了数组拥有的元素,只有两个,也就是说数组容量就是2,如果执行上面的代码,也会报错:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
    at test.TestArray.main(TestArray.java:14)
第三种写法

代码:

 public static void main(String[] args) {

        String[] strArr = {"0", "1"};

        strArr[10] = "145";
    }

这种写法也是直接说明了数组的元素,同样无法超出容量范围。

总结:
以上三种写发,实际上是都必须指定数组的长度,超出长度就会报错。

扩容

集合和队列都有使用数组的实现,这些实现是允许一直添加的(直到溢出为止),这些实现都不是固定的长度的数组可以支持的,必须实现数组的扩容,现在就看一下数组如何扩容。

任何一个数组长度都是固定的,所谓扩容就是定义一个新的数组,把原来数组的元素复制到新的数组中。
因此,可以根据这种思想自己实现扩容方法,也可以使用Java提供的方法。

Java提供了两种方法:
– System.arraycopy()
– Arrays.copyOf()

先看第一种方法System.arraycopy()
源码:

* @param      src      the source array.
     * @param      srcPos   starting position in the source array.
     * @param      dest     the destination array.
     * @param      destPos  starting position in the destination data.
     * @param      length   the number of array elements to be copied.
     * @exception  IndexOutOfBoundsException  if copying would cause
     *               access of data outside array bounds.
     * @exception  ArrayStoreException  if an element in the <code>src</code>
     *               array could not be stored into the <code>dest</code> array
     *               because of a type mismatch.
     * @exception  NullPointerException if either <code>src</code> or
     *               <code>dest</code> is <code>null</code>.
     */
    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

这是一个native方法,看不到实现,参数的注释非常的清楚,现在使用这个方法实现一个数组扩容。

测试代码:

public static void main(String[] args) {

        String[] strArr = {"0", "1", "2"};

        String[] newArr = new String[10];
        System.arraycopy(strArr, 0, newArr, 3, 3);
        strArr = newArr;
        for (String s : strArr) {
            System.out.println("元素:" + s);
        }
    }

输出结果:

元素:null
元素:null
元素:null
元素:0
元素:1
元素:2
元素:null
元素:null
元素:null
元素:null

可以看到现在strArr的长度是10,原来的元素复制到了3-5位上。

第二种实现方式Arrays.copyOf():
代码:

public static void main(String[] args) {

        String[] strArr = {"0", "1", "2"};

        //String[] newArr = new String[10];
        //System.arraycopy(strArr, 0, newArr, 3, 3);
        //strArr = newArr;
        strArr = Arrays.copyOf(strArr, strArr.length + 7);
        for (String s : strArr) {
            System.out.println("元素:" + s);
        }
    }

输出:

元素:0
元素:1
元素:2
元素:null
元素:null
元素:null
元素:null
元素:null
元素:null
元素:null

这种扩容方式,无法指定复制开始的位置,也无法指定复制到的位置;

源码:

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;
    }

可以看到,这种扩容方式实际上也是使用System.arraycopy方法,只不过位置默认为0。

总结

1、数组的长度是固定的;
2、数组的扩容实际上是新建一个数组;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值