找往期文章包括但不限于本期文章中不懂的知识点:
个人主页:我要学编程(ಥ_ಥ)-CSDN博客
所属专栏:数据结构(Java版)
顺序表的学习,点我
上面这篇博文是关于顺序表的基础知识,以及顺序表的实现。
目录
手动实现顺序表的源码:
分析Java 8 的 ArrayList 的源码
字段:
构造方法:
ArrayList本身的扩容机制和分配内存机制
ArrayList常见操作
ArrayList的遍历
平凡for循环遍历
for-each遍历
toString方法遍历
迭代器遍历
手动实现顺序表的源码:
下面是Java版的顺序表源码:
异常:
PosofAddException:
- public class PosofAddException extends RuntimeException{
- public PosofAddException() {
- }
- public PosofAddException(String msg) {
- super(msg);
- }
- }
复制代码 PosofGetException:
- public class PosofGetException extends RuntimeException{
- public PosofGetException() {
- }
- public PosofGetException(String msg) {
- super(msg);
- }
- }
复制代码 PosofSetException:
- public class PosofSetException extends RuntimeException{
- public PosofSetException() {
- }
- public PosofSetException(String msg) {
- super(msg);
- }
- }
复制代码 PosofRemoveException:
- public class PosofRemoveException extends RuntimeException{
- public PosofRemoveException() {
- }
- public PosofRemoveException(String msg) {
- super(msg);
- }
- }
复制代码 分析Java 8 的 ArrayList 的源码
实现了咱们本身写的顺序表了之后,就该来看Java本身的源码是怎么写的以及与我们的有什么差别?(注意:由于Java 17封装性太强,不好观看源码,因此下面的源码来自Java 8。)
字段:
elementData 就是我们本身实现的 elem 数组。
size 就是 usedSize ,也就是这个数组的有效元素的个数。
构造方法:
Java 8 实现的顺序表有三个构造方法。
带有一个 int 类型的参数的构造方法:
不带参数的构造方法:
带一个 Collection 类型的参数的构造方法:
下面的是其源码:
首先,我们得知道Collection 到底是这个啥?
根据上面这个图可以得知:Collection 是一个接口。
上面的参数先不看泛型,那就是Collection c 这个意味着只要实现了Collection 接口,就可以被当成实参传过来。而从上图的关系可知:ArrayList 继承了 AbstractLIst 这个抽象类 ,而且实现了LIst这个接口,而 LIst 这个接口拓展了 Collection 这个接口的功能。也就意味着 ArrayList 这个类实现了 Collection 这个接口。那么 ArrayList 就可以被当成参数传过来。
接下来,就是了解 <? extends E> ,?就可以当成是被传过来的 ArrayList 中的泛型,也就是说被传过来的 ArrayList 中的泛型要是 E 或者 E的子类。例如:
了解了这些,我们就来看源码吧。这个源码的大概意思是把传入的 ArrayList 中的元素给全部拷贝到原来的 ArrayList 的后面。
ArrayList本身的扩容机制和分配内存机制
既然我们在创建一个顺序表的时间,原本是空,那么当我们去增加元素的时间,扩容的机制又是如何呢?
上面是分析过程(可忽略),总之,得出了下面这个结论:
当顺序表为空时,我们如果去增加元素,就会初始化一个大小10的数组。而且数组在满了之后,会按照1.5倍的扩容方式来扩容。如果用户所需大小凌驾预估1.5倍大小,则按照用户所需大小扩容。
ArrayList常见操作
ArrayList常用方法 boolean add(E e)尾插evoid add(int index, E element)将 e 插入到 index 位置boolean addAll(Collection<? extends E> c)将c 中的元素举行尾插E remove(int index)删除 index 位置元素boolean remove(Object o)删除碰到的第一个oE get(int index)获取下标index位置元素E set(int index, E element)将下标 index 位置元素改为 elementvoid clear()清空boolean contains(Object o)判断是否在顺序表中int indexOf(Object o)返回第一个o所在下标int lastlndexOf(Object o)返回最后一个o的下标List<E> subList(int fromlndex, int tolndex)截取部门list 大部门方法,我们都很认识。因此这里只展示 addAll()方法 和 subList 方法。
addAll () 方法可以实现 ArrayList 的带Collection 类型的参数的构造方法。
从上面打印的效果可以看出来,ArrayList 是重写了toString 方法的。
从这里我们就可以看出来,被分割的数组应该是下面这样:
ArrayList的遍历
平凡for循环遍历
- public class Test {
- public static void main(String[] args) {
- ArrayList<Integer> arrayList = new ArrayList<>();
- arrayList.add(1);
- arrayList.add(2);
- arrayList.add(3);
- for (int i = 0; i < arrayList.size(); i++) {
- System.out.print(arrayList.get(i)+" ");
- }
- }
- }
复制代码 for-each遍历
- public class Test {
- public static void main(String[] args) {
- ArrayList<Integer> arrayList = new ArrayList<>();
- arrayList.add(1);
- arrayList.add(2);
- arrayList.add(3);
- for (Integer x : arrayList) {
- System.out.print(x+" ");
- }
- }
- }
复制代码 toString方法遍历
- public class Test {
- public static void main(String[] args) {
- ArrayList<Integer> arrayList = new ArrayList<>();
- arrayList.add(1);
- arrayList.add(2);
- arrayList.add(3);
- System.out.println(arrayList.toString());
- }
- }
复制代码 迭代器遍历
- public class Test {
- public static void main(String[] args) {
- ArrayList<Integer> arrayList = new ArrayList<>();
- arrayList.add(1);
- arrayList.add(2);
- arrayList.add(3);
- // 调用iterator方法生成一个迭代器,用Iterator<E>来接收
- Iterator<Integer> integerIterator = arrayList.iterator();
- // 如果下一个元素有值话,就进入while循环,并且打印下一个值,最后自己往后走
- while (integerIterator.hasNext()) {
- System.out.print(integerIterator.next()+" ");
- }
- }
- }
-
复制代码 只要是实现了 Iterator 接口就可以利用迭代器的方式来遍历。就是下面这张图:
好啦!本期 数据结构之ArrayList与顺序表(上)的学习就到此结束啦!我们下一期再一起学习吧!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |