【JAVA数据结构小记】—ArrayList动态数组

首先
定义ArrayList类,类中定义所需参数

/**
  * 元素的数量
  */
 private int size;
 /**
  * 所有的元素
  */
 private E[] elements;

 private static final int DEFAULT_CAPACITY = 10;
 private static final int ELEMENT_NOT_FOUND = -1;	

有参构造:数组默认大小为10,小于10则取默认

public ArrayList(int capaticy) {
		capaticy = (capaticy < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capaticy;
		elements = (E[]) new Object[capaticy];
	}

无参构造:创建默认大小为10的数组

public ArrayList() {
		this(DEFAULT_CAPACITY);
	}

清除元素:数组中如果存入的是引用类型,那么数组节点存储的是该引用对象的内存地址,将所有节点的内存置空,就相当于清除所有节点

/**
	 * 清除所有元素
	 */
	public void clear() {
		for (int i = 0; i < size; i++) {
			elements[i] = null;
		}
		size = 0;
	}

返回元素数量

/**
	 * 元素的数量
	 * @return
	 */
	public int size() {
		return size;
	}

判断元素是否空:

/**
	 * 是否为空
	 * @return
	 */
	public boolean isEmpty() {
		 return size == 0;
	}

查看元素索引:若查看的这个元素为null(java是支持将对象数组存入空值的),所以首先判断该元素是否是空,若是,则返回该索引下标。若不为空,则开始非空比较,可以用到equal方法。

/**
	 * 查看元素的索引
	 * @param element
	 * @return
	 */
	public int indexOf(E element) {
		if (element == null) {  // 1
			for (int i = 0; i < size; i++) {
				if (elements[i] == null) return i; 
			}
		} else {
			for (int i = 0; i < size; i++) {
				if (element.equals(elements[i])) return i; // n
			}
		}
		return ELEMENT_NOT_FOUND;
	} 

是否包含某个元素

/**
	 * 是否包含某个元素
	 * @param element
	 * @return
	 */
	public boolean contains(E element) {
		return indexOf(element) != ELEMENT_NOT_FOUND;
	}

从某个位置插入一个元素:首先要考虑用户输入的这个位置是否已超过数组的界限

//越界校验
private void rangeCheckForAdd(int index) {
		if (index < 0 || index > size) {
			outOfBounds(index);
		}
	}

抛异常方法:

private void outOfBounds(int index) {
		throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size);
	}

因为是动态数组,插入后涉及到扩容问题,扩容采取了new出一个比之前数组更大的数组,承载之前数组中的数据,大小自取,这里是1.5倍。做法是利用到了位运算,这样比在原长度上直接*1.5倍效率高。
扩容方法的第一步,就是判断输入的容量数capacity是否比数组之前的oldCapacity小,若小,则直接返回(防止用户输错而报错,或者是胡乱输入),增加了程序的健壮性。这个点虽小,却值得学习。
最后将旧数据for循环转移至新数组,然后旧数组头部指向新数组的内存地址,完成。

/**
	 * 扩容方法
	 * 保证要有capacity的容量
	 * @param capacity
	 */
	private void ensureCapacity(int capacity) {
		int oldCapacity = elements.length;
		if (oldCapacity >= capacity) return;
		
		// 新容量为旧容量的1.5倍
		int newCapacity = oldCapacity + (oldCapacity >> 1);
		E[] newElements = (E[]) new Object[newCapacity];
		for (int i = 0; i < size; i++) {
			newElements[i] = elements[i];
		}
		elements = newElements;
		
		System.out.println(oldCapacity + "扩容为" + newCapacity);
	}

在指定位置插入元素:越界检查–>扩容–>插入部位挨个后移–>size自增

	/**
	 * 在index位置插入一个元素
	 * @param index
	 * @param element
	 */
	public void add(int index, E element) {
		rangeCheckForAdd(index);
		
		ensureCapacity(size + 1);
		
		for (int i = size; i > index; i--) {
			elements[i] = elements[i - 1];
		}
		elements[index] = element;
		size++;
	}

改变数组某一位置的值:首先也是越界检查,但是与添加方法不同,此时输入的index参数是不能等于数组长度的,必须严格小于,因此index等于size,也算越界。

private void rangeCheck(int index) {
		if (index < 0 || index >= size) {
			outOfBounds(index);
		}
	}

将旧值替换,然后返回

/**
	 * 设置index位置的元素
	 * @param index
	 * @param element
	 * @return 原来的元素ֵ
	 */
	public E set(int index, E element) {
		rangeCheck(index);
		
		E old = elements[index];
		elements[index] = element;
		return old;
	}

将元素添加至数组尾部:直接调用之前的add方法,index参数写到数组末尾即可(即数组的长度)

/**
	 * 添加元素到尾部
	 * @param element
	 */
	public void add(E element) {
		add(size, element);
	}

输入索引值,取得索引对应的值:越界检验–>取值

/**
	 * 获取index位置的元素
	 * @param index
	 * @return
	 */
	public E get(int index) {
		rangeCheck(index);
		return elements[index];
	}

移除某一位置的元素,且返回:越界检验–>新旧赋值–>元素前移–>删除元素内容置空,数组长度减一

/**
	 * 删除index位置的元素
	 * @param index
	 * @return
	 */
	public E remove(int index) {
		rangeCheck(index);
		
		E old = elements[index];
		for (int i = index + 1; i < size; i++) {
			elements[i - 1] = elements[i];
		}
		elements[--size] = null;
		return old;
	}

以上是我对于恋上数据结构视频中,动态数组部分的总结。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值