ArrayList:继承关系

继承关系

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{

ArrayList继承了AbstractList,实现了List,RandomAccess,Cloneable,Serializable

image-20210115094043609

Serializable标记性接口

类的序列化由实现java.io.Serializable接口的类启用。 不实现此接口的类将不会使任何状态序列化或反序列化。 可序列化类的所有子类型都是可序列化的。 序列化接口没有方法或字段,仅用于标识可串行化的语 义。

Java序列化就是指把Java对象转换为字节序列的过程

Java反序列化就是指把字节序列恢复为Java对象的过程。

Serializable源码介绍:

public interface Serializable {
}

Cloneable标记性接口

介绍 一个类实现 Cloneable 接口来指示 Object.clone() 方法,该方法对于该类的实例进行字段的复制是合 法的。在不实现 Cloneable 接口的实例上调用对象的克隆方法会导致异常 CloneNotSupportedException 被抛 出。简言之:克隆就是依据已经有的数据,创造一份新的完全一样的数据拷贝。

Cloneable源码介绍:

public interface Cloneable {
}

克隆的前提条件 :

  • 被克隆对象所在的类必须实现 Cloneable 接口
  • 必须重写 clone 方法

ArrayList的clone实现:

    public Object clone() {
        try {
            //调用object的clone方法,是native方法
            ArrayList<?> v = (ArrayList<?>) super.clone();
            //底层用的System.arraycopy方法,也是native方法
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }

RandomAccess标记性接口

List实现使用的标记界面,表明它们支持快速(通常为恒定时间)随机访问。此接口的主要目的是允许通用算法更改其行为,以便在应用于随机访问列表或顺序访问列表时提供良好的性能。

当施加到顺序访问列表(如LinkedList),用于操纵随机接入列表(如ArrayList)最好算法可以产生二次行为。 鼓励通用列表算法在应用如果应用于顺序访问列表之前提供较差性能的算法,并且如果需要改变其行为以确保可接受的性能,则检查给定列表是否为instanceof此接口。

人们认识到,随机访问和顺序访问之间的区别通常是模糊的。 例如,一些List实现提供渐近的线性访问时间,如果它们在实践中获得巨大但是恒定的访问时间。 这样的一个List实现应该通常实现这个接口。 根据经验, List实现应实现此接口,如果对于类的典型实例,此循环:

  //随机遍历
  for (int i=0, n=list.size(); i < n; i++)
         list.get(i); 

比这个循环运行得更快:

//顺序遍历  
for (Iterator i=list.iterator(); i.hasNext(); )
         i.next(); 

RandomAccess源码:

public interface RandomAccess {
}

所以:

进行判断:判断List是否实现RandomAccess,如果实现,那么推荐使用随机遍历方式迭代集合,否则推荐顺序方式迭代集合。

        ArrayList<Object> list = new ArrayList<>();
        if(list instanceof RandomAccess){
            for (int i = 0, size = list.size(); i < size; i++) {
                Object o = list.get(i);
                System.out.println(0);
            }
        }else{
            for(Object obj : list){
                System.out.println(obj);
            }
        }

AbstractList抽象类

此类提供的骨干实现的List接口以最小化来实现该接口由一个“随机访问”数据存储备份所需的工作(如阵列)。对于顺序存取的数据(如链接列表), AbstractSequentialList应优先使用此类。

要实现一个不可修改的列表,程序员只需要扩展这个类并提供get(int)和size()方法的实现。

要实现可修改的列表,程序员必须另外覆盖set(int, E)方法(否则会抛出一个UnsupportedOperationException )。 如果列表是可变大小,则程序员必须另外覆盖add(int, E)和remove(int)方法。

根据Collection接口规范中的建议,程序员通常应该提供一个void(无参数)和集合构造函数。

不像其他的抽象集合实现,程序员不必提供迭代器实现; 迭代器和列表迭代器由此类实现的,对的“随机访问”方法上:get(int) ,set(int, E) , add(int, E)和remove(int) 。

该类中每个非抽象方法的文档详细描述了其实现。 如果正在实施的集合承认更有效的实现,则可以覆盖这些方法中的每一种。

image-20210115110456682

原文地址:https://www.cnblogs.com/wwjj4811/p/14281055.html