动态数组

数组是一种顺序存储的线性表,所有元素的内存地址是连续的。

接口设计

◼ int size(); // 元素的数量
◼ boolean isEmpty(); // 是否为空
◼ boolean contains(E element); // 是否包含某个元素
◼ void add(E element); // 添加元素到最后面
◼ E get(int index); // 返回index位置对应的元素
◼ E set(int index, E element); // 设置index位置的元素
◼ void add(int index, E element); // 往index位置添加元素
◼ E remove(int index); // 删除index位置对应的元素
◼ int indexOf(E element); // 查看元素的位置
◼ void clear(); // 清除所有元素

java实现

public class ArrayList  {

    //用来记录存入元素的数量
    private int size;
    //用来存放元素的数组
    private E elements[];
    //默认容量为10
    private static final int DEFAULT_CAPACITY = 10;

    //没有找到的标识
    public static final int ELEMENT_NOT_FOUND = -1;

    /**
     * @param capaticy 数组的容量,如果小于默认容量,则使用默认容量
     *
     */
    public ArrayList(int capaticy) {
        //如果容量小于默认容量,则使用默认容量
        capaticy = capaticy < DEFAULT_CAPACITY ? DEFAULT_CAPACITY:capaticy;
        elements = (E[]) new Object[capaticy];
    }

    /*
     * 无参构造函数,默认容量为 DEFAULT_CAPACITY
     * */
    public ArrayList() {
        this(DEFAULT_CAPACITY);
    }

    /*
    * @description 向数组最后面添加元素
    * @param element 要添加的元素
    * */
    public void add(E element) {
        //向数组最后添加元素,就是像数组index=size添加
        add(size,element);
    }

    /*
    * @description 向数组index的位置,添加元素element
    * @param index
    * @param element
    * */
    public void add(int index,E element) {
        //先检查index是否合法
        checkRangeForAdd(index);
        //再要确保elements的容量有size + 1;
        ensureCapaticy(size + 1);
        //将elements中 [index,size-1]区间内的元素依次向后移一个位置,从最后开始移
        for (int i = size; i > index; i--) {
            elements[i] = elements[i - 1];
        }
        //将element插入到index位置
        elements[index] = element;
        size++;
    }

    /*
    * @description 移除index处的元素
    * */
    public E remove(int index) {
        //首先检查index是否合法
        checkRange(index);
        //先获取index的元素,以便最后返回
        E oldElement = elements[index];
        //将[index+1,size-1]区间的元素依次向前移动一个。
        for (int i = index; i < size - 1; i++) {
            elements[index] = elements[index + 1];
        }
        //更新size
        size--;
        return oldElement;
    }

    /*
    * @description 清空数组中所有元素
    * */
    public void clear() {
        //遍历elements,置为null
        for (int i = 0; i < size - 1; i++) {
            elements[i] = null;
        }
        size = 0;
    }

    public E set(int index, E element) {
        //首先检查index是否合法
        checkRange(index);
        //合法的话,先获取index的旧元素以便最后返回
        E oldElement = elements[index];
        //替换新元素
        elements[index] = element;
        return oldElement;
    }

    /*
    * 获取动态数组中元素的数量
    * */
    public int size() {
        return size;
    }

    /*
    * 判断该数组是不是为空
    * */
    public boolean isEmpty() {
        return size == 0;
    }

    /*
    * @description 判断该数组是否包含元素 element,遍历判断
    * @param element 要比对的元素
    * */
    public boolean contains(E element) {
        return indexOf(element) != ELEMENT_NOT_FOUND;
    }

    /*
    * @description 根据元素返回该元素的下标
    * @param
    * */
    public int indexOf(E element) {
        //首先判断element是否为null
        if (element == null) {
            //遍历数组,找到就返回下标i
            for (int i = 0; i < size; i++) {
                if (elements[i] == null) return i;
            }
        } else {
            //遍历数组,找到就返回下标i
            for (int i = 0; i < size; i++) {
                if (element.equals(elements[i])) return i;
            }
        }
        //如果上面都没找到,返回 ELEMENT_NOT_FOUND
        return ELEMENT_NOT_FOUND;
    }

    /**
     * @description 根据角标获取元素
     * @param index 要查询的角标
     */
    public E get(int index) {
        //首先检查角标是否越界
        checkRange(index);
        return elements[index];
    }

    /*
    * @description 检查index是否合法
    * */
    private void checkRange(int index) {
        if (index > size - 1 || index < 0) {
            throw new ArrayIndexOutOfBoundsException("index: "+ index +"越界,Size=" + size);
        }
    }

    /*
     * @description 对Add操作检查index是否合法,判断的依据为index是否大于0,是否不超过size。
     * */
    private void checkRangeForAdd(int index) {
        if (index < 0 || index > size) {
            throw new ArrayIndexOutOfBoundsException("index: "+ index +"越界,Size=" + size);
        }
    }

    /*
     * @description 确保element有capaticy的容量,如果不够,则进行扩容
     * */
    private void ensureCapaticy(int capaticy) {
        //如果elements长度大于等于capaticy, do nothing
        if (elements.length >= capaticy) return;
        // 如果不够,先创建一个容量为elements 1.5倍的新数组,使用位运算效率要高。
        E[] newElements = (E[]) new Object[elements.length + (elements.length >> 1)];
        // 再将旧元素从elements中已入newElements中
        for (int i = 0; i < elements.length; i++) {
            newElements[i] = elements[i];
        }
        // 用newElements替代elements
        elements = newElements;
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("size:" + size).append(",[");
        for (int i = 0; i < size; i++) {
            E element = elements[i];
            if (i != 0) stringBuilder.append(",");
            stringBuilder.append(element.toString());
        }
        stringBuilder.append("]");
        return stringBuilder.toString();
    }
}

OC实现

GLArrayList.h

@interface GLArrayList  : NSObject

#pragma mark - 初始化
- (instancetype) init;
- (instancetype) initWithCapaticy:(int)capaticy;
+ (instancetype) new __unavailable;

#pragma mark - 增
- (void) addElement:(ObjectType)element;
- (void) addElement:(ObjectType)element atIndex:(int)index;

#pragma mark - 删
- (ObjectType) removeAtIndex:(int)index;
- (void) clear;

#pragma mark - 改
- (ObjectType) setElement:(ObjectType)element atIndex:(int)index;

#pragma mark - 查
- (int) size;
- (BOOL) isEmpty;
- (BOOL) containsElement:(ObjectType)element;
- (ObjectType) getElementAtIndex:(int)index;
- (int) indexOfElement:(ObjectType)element;

@end

GLArrayList.m

// 数组默认容量
static int const GL_ARRAY_LIST_DEFAULT_CAPATICY = 2;
static int const GL_ARRAY_LIST_NOT_FOUND = -1;
typedef void * AnyObject;

@interface GLArrayList()
{
    //用来存放元素的数组
    AnyObject *_array;
    //用来记录_array中元素的数量
    int _size;
    //用来记录_array中的容量
    int _capacity;
}
@end

GLArrayList.m

@implementation GLArrayList
#pragma mark - 初始化
- (instancetype) init {
    if (self = [super init]) {
        _array = calloc(GL_ARRAY_LIST_DEFAULT_CAPATICY, sizeof(AnyObject));
        _size = 0;
        _capacity = GL_ARRAY_LIST_DEFAULT_CAPATICY;
    }
    return self;
}
- (instancetype) initWithCapaticy:(int)capaticy {
    if (self = [super init]) {
        _array = calloc(capaticy, sizeof(AnyObject));
        _size = 0;
        _capacity = capaticy;
    }
    return self;
}


#pragma mark - 增

/// 将元素添加至数组最后
/// @param element 要添加的元素
- (void) addElement:(id)element {
    [self addElement:element atIndex:_size];
}
- (void) addElement:(id)element atIndex:(int)index {
    //先确定index是否合法
    if (index < 0 || index > _size) {
        @throw [GLArrayIndexOutOfBoundsException exeptionWithIndex:index];
    }
    //首先确保有size + 1 的容量,如果没有要扩容
    [self ensureCapaticy:_size + 1];
    // 把[index,size - 1]区间内从后开始,依次向后挪动一个单位
    for (int i = _size; i > index; i--) {
        _array[i] = _array[i - 1];
    }
    //将element插入index处
    _array[index] = (__bridge_retained AnyObject)element;
    _size++;
}


/// 确保_array有Capaticy的容量
/// @param capaticy 容量
- (void) ensureCapaticy:(int)capaticy {
    //如果当前容量大于capaticy, do nothing
    if (_capacity >= capaticy) return;
    //否则进行扩容,创建一个新数组,扩容为当前容量的1.5倍
    int newCapaticy = _capacity + (_capacity >> 1);
    GLLog(@"capaticy:%d -> %d",_capacity,newCapaticy);
    AnyObject *newArray = calloc(newCapaticy, sizeof(AnyObject));
    //将所有元素移入新数组中
    AnyObject *oldArray = _array;
    for (int i = 0; i < _size; i++) {
        newArray[i] = oldArray[i];
    }
    _array = newArray;
    _capacity = newCapaticy;
    free(oldArray);
}

#pragma mark - 删
- (id) removeAtIndex:(int)index {
    //首先检查index是否合法
    if (index < 0 || index > _size - 1) {
        @throw [GLArrayIndexOutOfBoundsException exeptionWithIndex:index];
    }
    //取出要移除的元素
    AnyObject elementToRemove = _array[index];
    //将[index+1,size -1]区间内的元素,从前到后依次向前移动一个单位
    for (int i = index; i < _size - 1; i++) {
        _array[i] = _array[i + 1];
    }
    _size--;
    GLLog(@"will remove %@",elementToRemove);
    return (__bridge_transfer id)elementToRemove;
}
- (void) clear {
    //遍历释放元素
    for (int i = 0; i < _size; i++) {
        CFRelease(_array[i]);
    }
    _size = 0;
}

#pragma mark - 改
- (id) setElement:(id)element atIndex:(int)index {
    //先检查index是否合法
    if (index < 0 || index > _size - 1) {
        @throw [GLArrayIndexOutOfBoundsException exeptionWithIndex:index];
    }
    //取出最后的元素以便返回
    AnyObject oldElement = _array[index];
    //将element覆盖index的位置
    _array[index] = (__bridge_retained AnyObject) element;
    CFRelease(oldElement);
    return (__bridge id)oldElement;
}

#pragma mark - 查
/// 获取当前数组中元素的数量
- (int) size {
    return self->_size;
}
/// 数组是否为空
- (BOOL) isEmpty {
    return self->_size == 0;
}
/// 数组中是否包含element元素
/// @param element 要对比的元素
- (BOOL) containsElement:(id)element {
    //遍历元素
    for (int i = 0; i < _size; i++) {
        if ([element isEqual:(__bridge id)(_array[i])]) return YES;
    }
    return YES;
}
/// 获取下标为index的元素
/// @param index 下标
- (id) getElementAtIndex:(int)index {
    //首先检查index是否合法
    if (index < 0 || index > _size - 1) {
        @throw [GLArrayIndexOutOfBoundsException exeptionWithIndex:index];
    }
    return (__bridge id)_array[index];
}

/// 获取element对应的下标
/// @param element element
- (int) indexOfElement:(id)element {
    for (int i = 0; i < _size; i++) {
        if ([element isEqual:(__bridge  id)_array[i]]) return i;
    }
    return GL_ARRAY_LIST_NOT_FOUND;
}

#pragma mark -

- (NSString *)description {
    NSMutableString *des = [NSMutableString string];
    [des appendFormat:@"size=%d,[",_size];
    for (int i = 0; i < _size; i++) {
        if (i != 0) {
            [des appendString:@","];
        }
        [des appendFormat:@"%@",_array[i]];
    }
    [des appendString:@"]"];
    return des;
}

- (void)dealloc
{
    [self clear];
}

你可能感兴趣的:(动态数组)