CS61B - Data Structure 课程 ArrayList 扩容+JAVA对象游离

今日心情 :- )

CS61B课程中实现ArrayList 数组扩容


/*
* implement an array list
* 1. addLast()
* 2. getLast()
* 3. size()
* 4. get()
* */
public class AList<T> {

    private T[] item;
    private int size;

    // constructor
    public AList(){
        size = 0;
        item = (T[]) new Object[5];
    }
    /*
    * resize the array capacity
    * */
    private void resize(int capacity){

        T[] a = (T[]) new Object[capacity];
        System.arraycopy(item,0,a,0,size);
        item = a;

    }

    public void addLast(T x){
        // if the size is larger than the fixed length
        // need to expand the array size
        if(size == item.length){
            T[] a = (T[]) new Object[size*2];
            System.arraycopy(item,0,a,0,size);
            item = a;
        }
        item[size] = x;
        size += 1;
    }

    public T getLast(){
        return item[size-1];
    }

    public int size(){
        return size;
    }

    public T get(int x){
        return item[x];
    }

    public T removeLast(){
        T x = getLast();
        size -= 1;
        item[size] = null;
        return x;
    }

}

实现ArrayList 需要考虑使用的方法有:

(1)insert : 插入

(2)addFirst : 添加到数组首位

(3)addLast:添加到数组尾部

(4)getFirst:获取数组头部元素

(5)getLast:获取数组尾部元素

(6)size:获取当前数组元素总个数

(7)removeLast:删除数组末尾元素

设计时需要在addLast方法中考虑到扩容问题,因为数组的长度定义是固定的,一旦指定数组长度固定就不可改变,如果此时addLast 添加的元素个数 大于 实际数组的固定长度,此时如果不进行数组扩容就会导致溢出。数组的扩容方法:新建一个数组其长度大于原来的数组的长度,然后将原来数组中的元素拷贝到新建的数组中,然后再将新的元素添加到新的数组中。那就需要考虑每次扩容的长度是多少,这就涉及到程序运行的效率和内存空间的 trade off 问题,如果每次扩容的长度较小,操作时间过长且扩容频繁;如果每次扩容的长度过大,可能造成内容空间的利用率低下。所以选择每次扩容的长度需要考虑程序运行的效率和内存空间的 trade off 问题,选择合适的扩容长度。


JAVA中ArrayList的扩容实现

首先ArrayList的实现不是同步的: Note that this implementation is not synchronized

ArrayList 的初始容量是:10

增长函数:(推荐的增长是原来的容量右移一位) 

    private Object[] grow(int minCapacity) {
        int oldCapacity = elementData.length;
        if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            int newCapacity = ArraysSupport.newLength(oldCapacity,
                    minCapacity - oldCapacity, /* minimum growth */
                    oldCapacity >> 1           /* preferred growth */);
            return elementData = Arrays.copyOf(elementData, newCapacity);
        } else {
            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
        }
    }

Java 对象游离

    public T removeLast(){
        T x = getLast();
        size -= 1;
        item[size] = null;
        return x;
    }

Java的GC回收所有没有引用的对象。在我们对 removeLast() 的实现中,被删除元素的引用仍然存在于数组中,但实际上我们不会再用到这个元素,所以实际上这个元素就是个孤儿,没有谁会再访问它,但Java编译器不知道这一点。这种情况:即一个不需要的对象的引用被保留下来而从不访问,就可以认为这个对象是游离的。要避免这种情况的对象游离,只需将被删除数组元素的值设为null覆盖无用元素的引用,系统在覆盖这个元素为null之后就会识别并回收它的内存。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值