Java数据结构:ArrayList与顺序表2

前一篇文章中,我们学习了如何模拟实现ArrayList类中的增删查改方法等,以及在使用ArrayList数组时必须实例化对象,因为ArrayList类是一个泛型类,需要明确传递的参数类型。

现在接着学习ArrayList类中的细节。

四、ArrayList的使用

看看ArrayList的源码中的一些成员变量:

ArrayList的构造方法

|----------------------------------------|------------------------------|
| 方法 | 解释 |
| ArrayList() | 无参构造 |
| ArrayList(int initialCapacity) | 指定顺序表初始容量 |
| ArrayList(Collection<? extends E> c) | 利用其他 Collection 构建 ArrayList |

带参数的构造方法

1.ArrayList(int initialCapacity)

观看这个构造方法的源码:这个构造方法初始化了顺序表的容量

示例:构造一个具有10个容量的顺序表

在容量范围内,可以往数组中新增元素,但是ArrayList泛型类中已经规定了可以传递的参数类型,是Integer类型的参数,因此,只能传递整型类型的元素,而不能传递String类型的元素

2.ArrayList(Collection<? extends E> c)

观看这个构造方法的源码,它的参数是一个Collection接口类型的参数,表示只要实现了这个接口的,都是可以传参的

?:表示通配符 ,表示的是要传递的参数类型,这个通配符以继承 E 类为上界 ,即必须是 E 类或者 E 类的子类。

示例:

将list引用作为构造方法参数,而list是ArrayList<Integer>类型,即作为参数传递后,向上转型编变成了 Collection<? extends E>类型,根据类型推导,E就是Integer类型,?就是Integer,而在list引用中,本身就初始化了一些元素,那么当它作为参数传递给另一个构造方法时,会将这个元素也默认传递过去。

看运行结果,它会将自身增加的和其他的类的原来就有的元素打印出来:

如果这个构造方法参数不是继承于Integer类的,会编译报错:

无参数构造方法

观看无参数构造方法的源码:也就是没有初始化数组容量的构造方法,此时的数组是一个空数组,即长度为0,源码中也是将该无参构造方法赋值为一个空数组:

示例:

问题:这个无参构造方法,其实并没有给分配内存,那么为什么还可以add新增数组元素呢?

解决这个问题,我们先看看add方法的源码:

总结来说,就是在第一次add的时候,分配内存空间大小默认是10,如果后边add的时候,发现满了,那么就是在原始内存空间大小的基础上1.5倍进行扩容,即在原始内存空间大小的基础上增加5个内存空间;即顺序表会自动扩容。

五、ArrayLIst的常见操作

|----------------------------------------------|---------------------------|
| 方法 | 解释 |
| boolean add(E e) | 尾插 e |
| void add(int index,E element) | 将 e 插入到 index 位置 |
| boolean addAll(Collection<? extends E> c) | 尾插 c 中的元素 |
| E remove(int index) | 删除 index 位置元素 |
| boolean remove(Object o) | 删除遇到的第一个 o |
| E get(int index) | 获取下标 index 位置元素 |
| E set(int index,E element) | 将下标 index 位置元素设置为 element |
| void clear() | 清空 |
| boolean contains(Object o) | 判断 o 是否在线性表中/线性表中是否包含 o |
| int indexOf(Object o) | 返回第一个 o 所在下标 |
| int lastindexOf(Object o) | 返回最后一个 o 的下标 |
| List<E> sublist(int fromIndex,int toIndex) | 截取部分 list |

boolean addAll(Collection<? extends E> c)尾插 c 中的元素

示例:

运行结果:

boolean remove(Object o)删除遇到的第一个 o

示例:

运行结果:

为什么上述的代码中会出现一道红色的线呢?------ 其实这代表这个方法现在已经很少去使用了。

List<E> sublist(int fromIndex,int toIndex)截取部分 list

示例:

运行结果:

思考:使用sublist方法,是在原顺序表上进行截取呢,还是会重新创建一个顺序表,然后再在这个顺序表上截取呢?

我们可以用代码来验证,使用set方法在test中增加一个元素,然后再次打印一下list的内容,看看截取到的内容还是不是[1,2,3]

我们看运行的结果:

这就说明,使用sublist方法截取是在原来的顺序表中进行截取的。

即 subList()返回的是原列表指定范围的视图,它们共享底层数据存储。

六、ArrayList的遍历

ArrayList 可以使用三种方式遍历:for循环+下标、for-each、使用迭代器

1. for循环

需要使用到size()、get()方法

运行结果:

2. for-each遍历

运行结果:

3. 使用 iterator 迭代器遍历

我们看看iterator的源码:它的返回值是一个泛型类

如果直接打印,会是一串地址:

那么,如何打印内容呢?

------ 需要用到 hasNext方法和 next方法。

hasNext() 和 next()

这两个方法的作用:

比如,有一组数据 1 2 3 4 5,当使用 hasNext 方法检测到下一个位置有元素时,再使用 next 方法可以返回这个 下一个位置元素 ,一直循环访问,知道结束。

运行结果:

4. 使用 ListIterator 迭代器遍历

运行结果:

使用 LIstIterator 迭代器扩展
hasPrevious() 和 previous()

这两个方法的作用:

注意:是从列表的最后一个元素的后一个位置开始遍历的,也就是反向遍历。

运行结果:

一道练习题

题目:删除第一个字符串中出现的所有第二个字符串中出现的字符

使用 列表list 的方式解决。

示例:输入: s1 = hello world s2 = eord

输出: list = hll wl

思路:创建一个列表,使用 contains 方法,它的作用是判断该元素是否在线性表中/线性表中是否包含该元素。

如果第二个字符串中包含第一个字符串中的字符,就不add放入如列表中,否则,放入列表中,然后返回列表。

注意:contains方法的返回值是String类型,ArrayList类的参数是Character字符类型(因为列表中存储的是一个个字符)

运行结果:

如果运行结果不想要有 ,的出现,可以使用size和get方法将列表中的内容一个个打印出来:

运行结果:

相关推荐
Fency咖啡2 小时前
Spring 基础核心 - SpringMVC 入门与请求流程
java·后端·spring·mvc
FrankYoou2 小时前
Spring Boot 自动配置之 Spring transaction
java·spring boot·spring
数字化顾问3 小时前
从索引失效到毫秒级响应——SQL 优化实战案例:从慢查询到高性能的完整指南之电商大促篇
java·开发语言·数据库
珹洺3 小时前
Java-Spring 入门指南(十六)SpringMVC--RestFul 风格
java·spring·restful
卷Java3 小时前
饼状图修复总结
java·spring boot·uni-app·echarts
oioihoii3 小时前
从汇编角度看C++优化:编译器真正做了什么
java·汇编·c++
Jiezcode3 小时前
LeetCode 148.排序链表
数据结构·c++·算法·leetcode·链表
那个松鼠很眼熟w4 小时前
1.多线程基础概念
java
聪明的笨猪猪4 小时前
Java 集合 “Map(1)”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试