1、Stack的简单介绍
- Stack的继承于Vector的动态数组队列
- Stack必须要满足于先进后出(FILO,First In Last Out)的结构
- Stack的线程安全的,主要方法都被synchronized所修饰
- Stack是动态大小的数组结构,底层为Object类型数组,每次增长为自身的一倍,初始容量为10
Tips
Stack的使用例子
①数值转换
②语法检查,符号成对出现
③数制转换等
2、Stack的构造函数
public Stack() {
}
只存在一个默认为空的构造函数
3、Stack的继承于接口实现
首先我们翻开Stack的源码
public
class Stack<E> extends Vector<E>
我们发现Stack的源码中只存在一个继承于Vector
我们便打开Vector
根据继承关系,一层一层推到出Vector的继承情况
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
①首先继承了AbstractList这个抽象类
②实现了List,RandomAccess,Cloneable,和序列化接口(java.io.Serializable)
Tips
1、什么是RandomAccess
答:RandomAccess接口实际上是一个标志性接口,你实现了这个接口代表你具有随机访问数据的能力(既通过数组下标直接访问数据)由此可知LinkedList肯定不会实现这个接口,因为它无法通过下标访问
public interface RandomAccess {
//RandomAccess,java源码里面什么都没有
}
2、Cloneable接口的作用
答:Cloneable接口也是一个标记性接口,实现这个接口代表着你可被clone,能够使用Object.clone()方法
public interface Cloneable {
//和上面的随机访问接口一样,不具有任何代码
}
3、什么是序列化
答:
把对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为对象的过程称为对象的反序列化。
对象的序列化主要有两种用途:
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
2) 在网络上传送对象的字节序列。
通俗的来说就是Vector内的数据可以保存在你的硬盘上
4、什么是List接口
我们打开List接口的源码
public interface List<E> extends Collection<E>
一上来展示的就是List接口继承与Collection接口,那我们再翻到Collection接口
public interface Collection<E> extends Iterable<E>
这时我们发现,怎么还有接口,那么继续往上翻
public interface Iterable<T>
这下终于没有接口了,舒服了。。。。
这时我们发现 Iterable迭代器接口是Vector的顶级父类,这三个接口继承到底让List接口获得了那些功能呢
①Iterable接口
public interface Iterator<E> {
/**
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
Iterator<T> iterator();
// 1.8新增了两个方法,暂不讨论
}
上面的代码说明表示会返回一个Iterator类型的变量
Iterator是迭代器接口,这就表明获得了一个迭代器
所以说,Iterable使List接口获得了迭代器功能
②Collection接口
public interface Collection<E> extends Iterable<E> {
// Query Operations
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
<T> T[] toArray(T[] a);
boolean add(E e);
boolean remove(Object o);
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
void clear();
boolean equals(Object o);
int hashCode();
}
Collection是List和set接口的父类,他提供了操作数据的基本方法名称
由此可知Collection使得List获得了基本操作方法的名称
③List接口
List接口继承了上述两个接口的所有特性,但是List接口代表着的是有序的Collection接口
即它用某种特定的插入顺序来维护元素顺序。用户可以对列表中每个元素的插入位置进行精确地控制,同时可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素
5、什么是AbstractList抽象类
我们首先打开AbstractList抽象类的源码
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
到这里我们发现了一个我们熟悉的List接口,但是还没结束,继续翻
public abstract class AbstractCollection<E> implements Collection<E>
到这里呢,我们又见到了我们熟悉的Collection接口
那么问题来了,我们为什么要创建一个AbstractCollection抽象类呢?
在此呢,我们需要复习几个概念
①当一个类实现某一个接口时,必须要实现这个接口的所有方法
②当一个类继承某一个类时,可以重写也可以不重写父类的方法
③抽象类是具有抽象方法的类,有抽象方法的类一定是抽象类,没有抽象方法的类也可能是抽象类
④抽象类无法创建实例,必须被继承后重写抽象方法
答:当我们需要实现Collection接口时,我们必须重写Collection接口中的全部方法,而AbstractCollection则帮我们实习了大多数的方法,我们只需要重写其中的几个方法,即可完成Collection接口的使用
未实现的方法为
public abstract Iterator<E> iterator();
public abstract int size();
同理
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
在AbstractList抽象类中,实现了List的大多数方法,只剩下几个必须要子类实现的函数没有实现
比如add(), set(),remove(),还有size()
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
如不重写add()方法就会抛出异常
那么到目前为止,我们发现了AbstractList抽象类继承了AbstractCollection抽象类
①AbstractCollection抽象类完成了Collection接口的基本方法但还保留了抽象方法等待子类去重写实现
②AbstractList抽象类进一步完善了AbstractCollection抽象类的方法,使得其变成了表结构,也就是说数据开始有序起来,在几个关键函数中AbstractList强制子类重写方法不然会爆出异常