您的位置:首页 > 编程语言 > Java开发

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

2019-05-10 11:56 190 查看

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: