[Java学习笔记] List 接口下的ArrayList类

ArrayList——线性表

ArrayList类作为List 接口的大小可变数组的实现,实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。(此类大致上等同于 Vector 类,除了此类是不同步的。)

构造器

  • ArrayList()
    构造一个初始容量为 10 的空列表。
  • ArrayList(Collection<? extends E> c)
    构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
  • ArrayList(int initialCapacity)
    构造一个具有指定初始容量的空列表。

常用方法

  • boolean add(E e)
    将指定的元素添加到此列表的尾部。

  • void add(int index, E element)
    将指定的元素插入此列表中的指定位置。

  • boolean addAll(Collection<? extends E> c)
    按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。

  • E get(int index)
    返回此列表中指定位置上的元素。

  • E remove(int index)
    移除此列表中指定位置上的元素。

  • boolean remove(Object o)
    移除此列表中首次出现的指定元素(如果存在)。

  • Object[] toArray()
    按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。

  • T[] toArray(T[] a)
    按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。

  • boolean contains(Object o)
    如果此列表中包含指定的元素,则返回 true。

  • int indexOf(Object o)
    返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。

  • boolean isEmpty()
    如果此列表中没有元素,则返回 true

  • int lastIndexOf(Object o)
    返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。

下面对ArrayList作模拟实现MyArrayList

public class MyArrayList {
	private Object[] list = new Object[10];//这是ArrayList的底层实现,维护了一个数组!
	/**这是记录表内有效(非null)元素的个数**/
	private int size = 0 ;
	public void add(Object obj) {//直接添加至尾部
		add(size,obj);
	}
	/**添加至下标index处,后面元素均后移一位**/
	public void add(int index , Object obj) {
		if(index < 0 || index > size)
			throw	new ArrayIndexOutOfBoundsException(index);
		if(size >= list.length)//扩容
			list = Arrays.copyOf(list, list.length * 2);
		System.arraycopy(list, index, list, index+1, size - index);//index位置以后的元素后移一位
		list[index] = obj;
		size++;
	}
	public int size() {
		return this.size;
	}
	public Object remove(Object obj) {
		int dele = indexOf(obj);
		if(dele != -1)
			return remove(dele);
		return null;
	}
	public Object remove(int index) {
		checkIndex(index);
		Object oldelement = list[index];
		System.arraycopy(list, index+1, list, index, size - index - 1);//删除时直接将index+1以后的元素前移一位即可
		size --;
		return oldelement;
	}
	public Object get(int index) {
		checkIndex(index);
			return list[index];
	}
	public Object set(int index, Object newobj) {
		checkIndex(index);
		Object old = list[index];
		list[index] = newobj;//替换为newobj
		return old;
	}
	private void checkIndex(int index) {
	//这是为了检查index的合法性,对于不合法的index直接以抛出异常的形式终止
		if(index <0	||	index >= size)
			throw	new ArrayIndexOutOfBoundsException();
	}
	public int indexOf(Object obj) {
		for(int i = 0 ; i < this.size ; i ++)
			if(list[i].equals(obj))
				return i;
		return -1;
	}
	@Override
	public String toString() {
		StringBuilder str = new StringBuilder("[");
		for(int i = 0 ; i < size ; i ++)
				str.append(list[i]+", ");
		if( ! this.isEmpty())
			str.delete(str.lastIndexOf(","),str.length());
		str.append(']');
		return str.toString();
	}
	public boolean contains(Object obj) {
		for(Object o : list)
		{
			if(obj.equals(o))
				return true;
		}
		return false;
	}
	public boolean isEmpty() {
		return this.size == 0;
	}
	
}

另外看到ArrayList类中的toArray()方法,它重载了一次,我们发现这两个方法实际上返回的数组是一个新数组,并非与本对象数组共享空间!

        public Object[] toArray() {
            return a.clone();//Java中的一维数组在调用clone方法是一种深克隆,实现的是重新分配空间并复制原数组内容
        }
        
`		public <T> T[] toArray(T[] a) {
            int size = size();
            if (a.length < size)
                return Arrays.copyOf(this.a, size,
                                     (Class<? extends T[]>) a.getClass());
            System.arraycopy(this.a, 0, a, 0, size);//将本对象的核心数组拷贝至传入数组
            if (a.length > size)
                a[size] = null;
            return a;
        }``
        

Arrays类中有这么一个方法

public static <T> List<T> asList(T... a) {
            return new ArrayList<>(a);//该ArrayList对象不是util包内的Arraylist,是java.util.Arrays.ArrayList
        }

该方法返回的是一个List接口引用的ArrayList(非真正的ArrayList,是Arrays的内部类对象,不能进行add操作),此时传入的数组a被用来构造这个对象,并且a与该对象内的数组是共享空间的,也即是同一个数组,改一必改另一,此时若想构建传统ArrayList对象,可以调用ArrayList(Collection<? extends E> c) 构建新的不共享内存的真ArrayList

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值